开发者

Why is "operator bool()" invoked when I cast to "long"?

开发者 https://www.devze.com 2022-12-18 18:19 出处:网络
I have the following class: class MyClass { public: MyClass( char* what ) : controlled( what ) {} ~MyClass() { delete[] controlled; }

I have the following class:

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;
};

This is compiled with Microsoft SDK that has the following typedefs:

typedef long LONG_PTR;
typedef LONG_PTR LPARAM;

The calling code does the following:

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 );

Suddenly castResult is 1 - 开发者_运维技巧MyClass::operator bool() is invoked, it returns true which is converted to 1. So instead of passing the address I pass 1 into SendMessage() which leads to undefined behaviour.

But why is operator bool() invoked in the first place?


It's one of the known pitfalls of using operator bool, that is a aftershock of C inheritance. You'd definitively benefit from reading about the Safe Bool Idiom.

In general, you didn't provide any other matchable casting operator, and bool (unfortunately) is treated as a good source for arithmetic casting.


operator bool is the best match, because char* and void* can't be converted to long without an explicit cast, unlike bool:

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


You cannot implicitly cast a T* to long. But you can cast a bool to long.

So the operator bool is used.

You have to define a operator LPARAM.

0

精彩评论

暂无评论...
验证码 换一张
取 消