我对某些代码感到有些困惑。我必须使用方法getToto()
的返回类型,它通常返回std::string
,但在一种情况下它返回false
(它是我必须使用的库的一部分,我不能修改它)。我明白这相当于一个空指针。但我找不到合适的方法来抓住它!
Test.cpp的
static std::string getToto(){
char buffer[1024];
if ( CTX_Get_Env(buffer, "Toto", 1024) )
return false;
return buffer;
}
如果我尝试
const char* returned = Test::getToto().c_str();
if (returned==NULL){
std::cout<< "null pointer"<<std::endl;
}
我在运行时遇到错误
在抛出'std :: logic_error'
的实例后终止调用what():basic_string :: _ S_construct NULL无效
抱歉,我的C ++水平相当低。
答案 0 :(得分:3)
这取决于。返回逻辑中的空字符串部分,或者它是一种异常情况。
如果不应该发生,你应该抛出错误。
如果字符串为空是可以的,那么你应该只返回一个空字符串:
return std::string();
它按原样编译的原因是false
被解释为0
,它是NULL
,可以是char*
,因此尝试使用字符串从它构建。但是,从std::string
指针构造NULL
无效,这就是您获得异常的原因。
以下是我编码的方式:
static std::string getToto(){
char buffer[1024];
if ( CTX_Get_Env(buffer, "Toto", 1024) )
throw InvalidDataInBufferException();
return buffer;
}
如果字符串不应为空,或
static std::string getToto(){
char buffer[1024];
if ( CTX_Get_Env(buffer, "Toto", 1024) )
return std::string();
return buffer;
}
如果字符串为空可以。
答案 1 :(得分:3)
使用std::string(const char*)
初始化隐式false
构造函数,该构造函数被解释为空指针。标准不允许从空指针构造std::string
。在您的平台上,这会导致抛出异常。如果您无法修改该功能,可以将函数调用放在try块中,但请注意这绝不能保证在其他平台上工作。
try {
std::string returned = Test::getToto().c_str();
const char* c = returned.c_str();
} catch(...) {
// handle the error
}
注1 :如果从空指针初始化std::string
,则不需要实现引发异常,因此调用getToto()
函数可能会导致未定义的行为。 try-catch
块仅在您的实现抛出异常时才有用,因此不是可移植的解决方案。这也意味着应该避免通过调用未定义的行为来保存库函数getToto()
。
Note2 :异常隐藏了另一个错误,在这里:
const char* returned = Test::getToto().c_str();
Test::getToto()
返回一个临时字符串,您不指定该字符串。你的returned
指针悬空了。在我的代码示例中,我将返回值分配给std::string
,然后获取指向其内部char数据的指针。
答案 2 :(得分:0)
你应该明白,即使getToto()确实返回,你也有异常。没有办法从函数返回字符串中“返回false”并且不会出现异常。这只是一个错误。 您可以使用try / catch块覆盖它,如下所示:
const char* returned = NULL;
try{
returned = Test::getToto().c_str();
}catch(std::exception& e){
std::cout << "null pointer" << std::endl;
}
但这仍然是一件坏事。