【问题标题】:Why is "operator bool()" invoked when I cast to "long"?为什么当我转换为“long”时会调用“operator bool()”?
【发布时间】:2011-01-09 21:30:56
【问题描述】:

我有以下课程:

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

【问题讨论】:

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


    【解决方案1】:

    这是使用运算符 bool 的已知缺陷之一,这是 C 继承的余震。你肯定会从阅读Safe Bool Idiom 中受益。

    一般来说,您没有提供任何其他可匹配的强制转换运算符,并且 bool(不幸的是)被视为算术强制转换的良好来源。

    【讨论】:

      【解决方案2】:

      operator bool 是最佳匹配,因为 char*void* 不能在没有显式转换的情况下转换为 long,这与 bool 不同:

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

      【讨论】:

        【解决方案3】:

        您不能将 T* 隐式转换为 long。但是您可以将 bool 转换为 long。

        所以使用operator bool

        你必须定义一个operator LPARAM

        【讨论】:

        • 或者更确切地说删除所有的转换运算符。如果您希望允许在布尔上下文中评估对象(在标准 C++ 库中使用,但例如使 std::cout << std::cin; 产生一些不直观的结果),则只有 operator void* 被认为是相对良性的,即使有更可靠的技术。
        猜你喜欢
        • 2017-11-28
        • 1970-01-01
        • 2011-04-18
        • 2010-11-21
        • 2023-02-02
        • 1970-01-01
        • 1970-01-01
        • 2021-09-14
        相关资源
        最近更新 更多