2010-11-08 208 views
4
class Test 
{ 
public: 
    operator Test *() { return NULL; }; 
}; 

int main() 
{ 
    Test test; 
    if (test == NULL) 
     printf("Wtf happened here?\n"); 

    return 0; 
} 

這段代碼是怎麼編譯的? Test如何獲得比較運算符?是否有一些隱含的鑄造過程?那個重載操作符甚至意味着什麼(並且做了什麼)?運算符重載「運算符T *()」產生比較運算符?

回答

7

重載運營商增加了轉換,從TestTest *。由於沒有比較運算符定義以TestNULL作爲參數,因此嘗試存在任何存在的轉換運算符。 operator Test *返回與NULL相當的類型,因此使用它。

+0

NULL是一件特別的事情嗎?我認爲它總是被定義爲0,而不是一個特殊的指針。 – 2010-11-08 23:42:09

+0

NULL是0(在C++中),但整數立即數零是特殊情況。它可以轉換爲任何指針類型。 – 2010-11-08 23:46:29

-3

你還沒有定義你自己的比較,因此他編譯器已經爲你做了一個。然而,你已經試圖重載解引用操作符......我不明白爲什麼。

要定義你的==操作符的功能

this

+2

這絕對不是發生了什麼。 operator ==沒有被默認定義。而且他沒有讓解引用操作符過載。 – 2010-11-08 23:44:07

0

+1爲Baffe的迴應。如果你想通過*以某種方式公開一些包裝對象的實例,那麼也許你應該重載->而不是重載*

class Bar 
{ 
public: 
    void Baz() { ... } 
} 

class Foo 
{ 
private: 
    Bar* _bar; 
public: 
    Bar* operator ->() { return _bar; } 
} 

// call like this: 
Foo f; 
f->Baz(); 

只是一個想法。

1

是的,您已將隱式轉換添加到T*,因此編譯器將使用它與NULL進行比較。

其他一些注意事項:

NULL是0簡寫,因此這意味着,反對0比將被允許。 (但對於其他整數值則不是這樣,0是特殊的。)

您的類型也可以在布爾上下文中隱式使用。也就是說,這是合法的:

Test test; 
if (test) 
{ 
    // ... 
} 

C++0x allows you to specify an explicit keyword轉換運營商不允許這樣的事情。

隱式轉換爲指針類型通常很可疑。除了在意外情況下發生轉換的缺陷之外,如果對象擁有返回的指針,它可能會導致危險情況。例如,考慮允許隱式轉換爲const char*的字符串類:

BadString ReturnAString(); 

int main() 
{ 
    const char* s = ReturnAString(); 
    // Uh-oh. s is now pointing to freed memory. 

    // ... 
}