运算符重载“运算符T *()”产生比较运算符?

运算符重载“运算符T *()”产生比较运算符?

问题描述:

class Test 
{ 
public: 
    operator Test *() { return NULL; }; 
}; 

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

    return 0; 
} 

这段代码是怎么编译的? Test如何获得比较运算符?是否有一些隐含的铸造过程?那个重载操作符甚至意味着什么(并且做了什么)?运算符重载“运算符T *()”产生比较运算符?

重载运营商增加了转换,从TestTest *。由于没有比较运算符定义以TestNULL作为参数,因此尝试存在任何存在的转换运算符。 operator Test *返回与NULL相当的类型,因此使用它。

+0

NULL是一件特别的事情吗?我认为它总是被定义为0,而不是一个特殊的指针。 – 2010-11-08 23:42:09

+0

NULL是0(在C++中),但整数立即数零是特殊情况。它可以转换为任何指针类型。 – 2010-11-08 23:46:29

你还没有定义你自己的比较,因此他编译器已经为你做了一个。然而,你已经试图重载解引用操作符......我不明白为什么。

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

this

+2

这绝对不是发生了什么。 operator ==没有被默认定义。而且他没有让解引用操作符过载。 – 2010-11-08 23:44:07

+1为Baffe的回应。如果你想通过*以某种方式公开一些包装对象的实例,那么也许你应该重载->而不是重载*

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

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

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

只是一个想法。

是的,您已将隐式转换添加到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. 

    // ... 
}