2012-07-31 77 views
0

所以我今天遇到了一個錯誤,其中一個NULL被傳遞給構造函數的參數列表,這導致應用程序中斷。奇怪的是,編譯器並沒有禁止這種情況發生。由於參數列表發生了變化,直到現在才發現問題。請參閱以下代碼片段:當std :: string是參數時,如何禁止在參數列表中傳遞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對象編譯器不會做任何事情。沒有警報響起,你留下了撓頭,當程序崩潰時發生了什麼。我認爲應該有辦法來防止這種情況的發生。有什麼可以解決這個問題嗎?編譯器中是否有應該打開的東西?

回答

8

實際上,它並不是真正的NULL,它是通過引用傳遞的。

std::string有一個轉換構造函數,它需要一個char const*NULL是一個空指針常量,因此可以在預期使用char const*時使用它,因此std::string對象是由此空指針構造的。這種構造產生未定義的行爲。

向用戶提供更好的警告的一個選擇是添加另一個具有char const*參數的構造函數。這樣,如果傳入null,就可以輕鬆地在構造函數中添加斷言。這不是編譯時檢查,但如果經常遇到此問題,它可能比沒有更好(因爲它的價值,我不記得曾經遇到過這個問題,所以我認爲這是不值得的努力)。

+0

爲什麼它會產生未定義的行爲? – 2012-07-31 22:21:00

+1

@LuchianGrigore:該特定'std :: string'構造函數的參數在合約中不能爲NULL。 – 2012-07-31 22:22:02

+0

@LuchianGrigore:'std :: basic_string'的規範要求指針不爲null。 – 2012-07-31 22:23:01

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" 
相關問題