说我写了一些函数myFunc可以抛出const char *例外:
void myFunc()
{
int returnCode = whatever();
if (!returnCode)
{
std::string msg;
msg.append("whatever function failed");
std::cerr << msg << std::endl; // print warning message
throw msg.c_str(); // throw warning message as exception
}
}
后来我就这样使用它了:
void myProgram()
{
try
{
myFunc();
}
catch(const char* str)
{
// is 'str' string memory valid here?
}
}
我意识到这对于异常使用来说并不是一个好的策略:更好地抛出并捕获异常类,而不是字符串。但我很好奇这里涉及的范围。
答案 0 :(得分:1)
msg.str()
会返回临时 std::string
。由于在语句;
的末尾删除了临时值,c_str()
语句的内容在throw ... ;
语句通过异常机制离开作用域终止时变为未定义。 / p>
(const char*
临时的生命周期显然已扩展到catch
处理程序,但由于底层缓冲区消失,这无济于事。)
投掷std::string
(即throw msg.str();
)会起作用,临时的生命周期将按预期延长。
答案 1 :(得分:1)
实际上c_str()
调用正在对一个临时(string
)对象进行操作,当你捕获它时指针将无效。
不仅如此,但由于stringstream
和string
可以进行分配,因此您需要确保不会因为堆问题而抛出。如果你因为内存不足而处于这种状态,那么你可能会在尝试创建异常时更加糟糕。您通常希望在特殊情况下避免堆分配。
您是否无法使用说runtime_error
或创建自己的例外类型?
答案 2 :(得分:1)
请注意,如果你说过:
throw "error";
你会没事的,因为字符串文字的生命周期是程序的生命周期。但不管怎样,不要这样做!
答案 3 :(得分:1)
std::string
itself 的可能性。
std::exception
保证在施工期间不会抛出异常,std::string
没有这样的保证。
另一种方法(对于类)是在类中声明私有std::string
对象。在throw
之前汇总错误消息,然后抛出c_str()
。这将引发const char*
异常,错误消息有效,直到从该类抛出下一个异常(这可能会再次修改错误字符串。)
可在此处找到一个简单示例:http://ideone.com/d9HhX