class Test
{
public:
operator Test * () { return NULL; };
};
int main()
{
Test test;
if (test == NULL)
printf("Wtf happened here?\n");
return 0;
}
这段代码是如何编译的? Test如何获得比较运算符?是否有一些隐含的演员?那个重载运算符甚至意味着什么?(&do)?
答案 0 :(得分:7)
重载运算符会添加从Test
到Test *
的转换。由于没有定义以Test
和NULL
作为参数的比较运算符,因此尝试了存在的任何转换运算符。 operator Test *
会返回与NULL
相当的类型,因此会使用它。
答案 1 :(得分: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.
// ...
}
答案 2 :(得分: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();
只是一个想法。
答案 3 :(得分:-3)