当std :: string是参数时,如何禁止在参数列表中传递NULL?

nnd*_*wan 0 c++

所以今天我遇到了一个bug,其中NULL被传递到构造函数的参数列表中,这导致应用程序中断.奇怪的是,编译器没有禁止这种情况发生.由于参数列表发生了变化,直到现在才发现问题.请参阅以下代码段:

该对象需要3个参数,密切关注std :: string&.

class Foo {
public: 
    std::string myName;
    unsigned int someVariable;
    void * ptr;

    Foo(const std::string&  name, void * aPtr, unsigned int variable);
    ~Foo();
}

Foo::Foo(const std::string&  name, void * aPtr, unsigned int variable) : myName(name), ptr(aPtr), someVariable(variable)
{
   // object constructed
}


int main(int argc, char* argv[])
{
   // construct an instance of Foo
   Foo foo(NULL /*whoops, passed in NULL when a string should be passed in*/,
           "foo", 
           0);   // program compiles as expected, A NULL pointer runtime error occurs when executed.
}
Run Code Online (Sandbox Code Playgroud)

所以基本上,如果你意外地为foo对象切换输入值,编译器就不会做任何事情.没有警报声响起,你在程序崩溃时发生了什么事.我认为应该有办法防止这种情况发生.有什么东西可以解决这个问题吗?是否应该打开编译器中的某些内容?

Jam*_*lis 8

实际上,它并不是真的NULL通过引用传递.

std::string有一个转换构造函数,需要一个char const*. NULL是一个空指针常量,因此它可以在char const*期望的地方使用,因此std::string从该空指针构造一个对象.这种结构会产生不确定的行为.

向用户提供更好警告的一个选项是添加具有char const*参数的另一个构造函数.这样,如果传入null,你可以在构造函数中轻松添加一个断言.这不是编译时检查,但如果你经常遇到这个问题,它可能总比没有好(因为它值得,我不记得了)曾经遇到过这个问题,所以我认为这不值得努力).

  • 创建一个私有构造函数,它将int作为第一个参数.现在,当某人传递NULL时,他们将得到"无法访问的构造函数"错误.您可能希望对nullptr_t执行相同的操作. (2认同)
  • @RaymondChen:这几乎没有增加成本......唯一可以无意中传递NULL作为`int`的情况是`NULL`或`0`(文字).所有其他`int`值都不会转换为`const char*`,因此它会捕获错误的情况并不多.同时,`const char*`可以为NULL,但仍然会被忽略."断言"是(意见)的方法.我从未遇到过这个错误,它真的需要解决吗?现在,如果我们谈论*whole*`string`接口......我很乐意删除`operator =(CharT)`,它允许相同类型的错误...... (2认同)