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

时间:2012-07-31 22:16:45

标签: 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.
}

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

2 个答案:

答案 0 :(得分:8)

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

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

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

答案 1 :(得分:1)

这就是我要做的事情:

    Foo(const std::string&  name, void * aPtr, unsigned int variable);
    ~Foo();
private:
    Foo(int, void*, unsigned int); // Do not implement.
                                   // This will generate a link time error when
                                   // NULL is used as the first parameter.

注意:如果没有这个改变,我会得到编译器错误(所以这显然不是你运行的代码)。但当我解决明显的错误时,我仍然得到:

n.cpp:27: error: invalid conversion from ‘const void*’ to ‘void*’
// This is caused by the parameter -> "foo"