我在C ++中使用一个非常简单的异常进行编码。
但这不符合我的预期。
我不知道为什么即使在调试模式下。
我附上了一张在捕获点处在eclipse调试模式下显示变量的图片。
我除了代码流将进入if
语句但它进入else
语句。
因为这个问题太简单了,我认为我对处理异常有误解,请修正我的理解。
throw "connection fail";
catch(const char* e){
if(e == "connection fail"){
clients.erase(client);
continue;
}else{
std::cout << e << std::endl;
assert(NULL);
}
}
答案 0 :(得分:5)
您很幸运,代码没有按预期工作,它可能有很好的机会,然后在您重新编写代码很长一段时间后就会崩溃。
if(e == "connection fail"){
上面的问题是你要比较两个指针(指向两个不同的字符串文字),而不是你期望的字符串本身。我之所以说它可能起作用的原因是因为允许编译器汇集字符串文字,这意味着它会在两个地方都使用相同的字符串文字副本,并且支票将会通过,让您相信代码正常工作。当然,并不能保证这种情况总是会发生,并且当你重新编译时,你的代码可能会在某一天静默地破解。
要实际比较字符串,请使用strcmp
,或将其中一个操作数转换为std::string
。
try {
throw "connection fail";
} catch( char const *e ) {
if(std::string(e) == "connection fail") {
std::cerr << "caught: " << e << std::endl;
}
}
更好的解决方案是抛出源自std::exception
的类型。我将您的代码更改为:
try {
throw std::runtime_error("connection fail");
} catch( std::exception const& e ) {
std::cerr << "caught: " << e.what() << std::endl;
}
答案 1 :(得分:2)
请不要抛出const char*
,这没有任何意义!
throw std::runtime_error("My Error");
catch (const std::runtime_error& e)
或创建自己的异常,其中包含指示异常详细信息的变量或指示问题的不同对象类型!然后你不需要进行任何字符串比较。
答案 2 :(得分:0)
您无法将C风格的字符串与==
进行比较,您必须使用strcmp
。大部分时间都是。
==
仅比较指针地址。在这种情况下,您有两个字符串,因此它们位于不同的地址,即使它们在字符串中可能包含相同的字符。
如果可以确保两个字符串实际上是内存中的相同位置,则可以使==
比较有效。这是一种让它发挥作用的方法:
static const char * connection_fail = "connection fail";
throw connection_fail;
catch(const char* e){
if(e == connection_fail){
// ...
更好的解决方案是不抛出字符串,而是抛出从std::exception
派生的对象。它们包含一个what()
方法,可用于获取描述错误的字符串。