为什么当我转换为“long”时会调用“operator bool()”?

时间:2010-01-27 10:06:34

标签: c++ visual-c++ casting operators

我有以下课程:

class MyClass {
public:
   MyClass( char* what ) : controlled( what ) {}
   ~MyClass() { delete[] controlled; }
   operator char*() const { return controlled; }
   operator void*() const { return controlled; }
   operator bool() const { return controlled != 0; }

private:
   char* controlled;
};

这是使用具有以下typedef的Microsoft SDK编译的:

typedef long LONG_PTR;
typedef LONG_PTR LPARAM;

调用代码执行以下操作:

MyClass instance( new char[1000] );
LPARAM castResult = (LPARAM)instance;
// Then we send message intending to pass the address of the buffer inside MyClass
::SendMessage( window, message, wParam, castResult );

突然castResult 1 - MyClass::operator bool()被调用,它返回true,转换为1。因此,我没有传递地址,而是将1传递给SendMessage(),导致未定义的行为。

但为什么首先调用operator bool()

3 个答案:

答案 0 :(得分:11)

这是使用operator bool的已知陷阱之一,这是C继承的余震。阅读有关Safe Bool Idiom的信息,你肯定会受益匪浅。

一般情况下,您没有提供任何其他匹配的铸造操作符,并且bool(不幸的是)被视为算术铸造的良好来源。

答案 1 :(得分:5)

operator bool是最佳匹配,因为与char*不同,void*long无法在没有明确演员的情况下转换为bool

long L1 = (void*)instance; // error
long L2 = (char*)instance; // error
long L3 = (bool)instance; // ok

答案 2 :(得分:2)

您不能隐含地将T*强制转换为long。但是你可以长期投出一个布尔。

因此使用了operator bool

您必须定义operator LPARAM