在C++中,类如何在构造函数中获取const std :: string&参数,但也处理NULL?

Mat*_*all 4 c++ string stl

我正在尝试使用std :: string参数创建类的方法,但它也处理NULL而不抛出异常.这是代码的示例:

class myString {
public:
    myString(const std::string& str) : _str(str) {}
    std::string _str;
};

int main() {
    myString mystr(NULL);
    printf("mystr = <%s>\n", mystr._str.c_str());
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

直觉上,你认为这个程序应该打印"mystr = <>"并成功退出,但是用g ++代替它会出现这个错误:

terminate called after throwing an instance of 'std::logic_error'  
what():  basic_string::_S_construct NULL not valid
Run Code Online (Sandbox Code Playgroud)

如何更改此类以便将NULL转换为""而不是抛出logic_error异常?

(后记:正如你所怀疑的那样,"真正的"实现比这个例子复杂一点,在构造函数中有几个参数,用_str做更多有趣的事情 - 并正确地保持私有.这个例子背后的动机是我们团队中的程序员将倾向于在此上下文中使用NULL以用于历史目的,并且编译器不会捕获这一点.重新训练每个人总是使用""是相对困难的.或者,一个聪明的解决方案将很容易)

P S*_*ved 11

这里实际发生的是NULL被解释为char const*并且正在尝试转换为std::string(您可以将类型的C字符串转换char*为STL字符串,对吧?).

要处理它,您可以添加另一个构造函数

class myString {
public:
    myString(const std::string& str) : _str(str) {}
    myString(const char* str) : _str(str==NULL?"":std::string(str)) 
    { /* and do something special in the body */ }
    std::string _str;
};
Run Code Online (Sandbox Code Playgroud)

但如果你不需要什么特别的东西,那就更好了

class myString {
public:
    myString(const std::string& str = "") : _str(str) {}
    std::string _str;
};
int main() {
    myString mystr;  //no () here!
    printf("mystr = <%s>\n", mystr._str.c_str());
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 该代码是否会导致臭名昭着的"最令人烦恼的解析"或相关场景?通常显式调用null-arg构造函数就像在main()的第一行中那样做.我没有尝试自己编译. (2认同)

Fre*_*son 6

真的,你不能.NULL不是字符串.但这里有一些替代方案:

  • 您可以重载构造函数以省略字符串参数.

  • 您可以使用指针而不是引用.

  • 您可以将字符串参数默认为"".


dir*_*tly 5

你不能.你需要有一些能够传递引用的东西.你可以通过默认为空字符串来解决这个问题"".

或者,有另一个explicitctor:

class myString {
 public:
   myString(const std::string& str) : _str(str) {}
   explicit myString(const char* str = NULL) : _str(str?str:"") {}
   std::string _str;
};
Run Code Online (Sandbox Code Playgroud)