1

所以我今天遇到了一个错误,其中一个 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 对象的输入值,编译器不会做任何事情。没有响起警报,程序崩溃时您会摸不着头脑。我认为应该有一种方法可以防止这种情况发生。有什么可以解决这个问题的吗?编译器中有什么东西应该打开吗?

4

2 回答 2

8

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

std::string有一个转换构造函数,它接受一个char const*. NULL是一个空指针常量,所以它可以用在需要 a的地方,所以从这个空指针构造char const*一个对象。std::string这种构造会产生未定义的行为。

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

于 2012-07-31T22:19:54.887 回答
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"
于 2012-07-31T22:48:41.357 回答