当一个对象同时提供 `operator!` 和 `operator bool` 时,这在表达式 `!obj` 中使用?

Posted

技术标签:

【中文标题】当一个对象同时提供 `operator!` 和 `operator bool` 时,这在表达式 `!obj` 中使用?【英文标题】:When an object provides both `operator!` and `operator bool`, which is used in the expression `!obj`? 【发布时间】:2014-01-08 03:49:11 【问题描述】:

我遇到了一个我自己无法回答的问题。另外,我在谷歌和这里都没有找到答案。比如说,我想在 if 子句中“检查对象的有效性”,如下所示:

MyClass myObject;

// [some code, if any]

if (!myObject)

    // [do something]

MyClass 定义如下:

class MyClass

public:
    MyClass()  ;
    virtual ~MyClass()  ;
    bool operator!()
    
        return !myBool;
    ;
    operator bool()
    
        return myBool;
    ;
private:
    bool myBool = 0;
;

我现在的问题是:在这个 if 子句中实际使用了哪一个重载运算符?不管怎样,结果显然是一样的。

【问题讨论】:

我认为它会走阻力最小的道路,并致电operator!... 在读完这篇文章之前不要考虑重载 bool:***.com/questions/6242768/… 是的,只需执行operator bool 并明确说明即可。无论如何,operator! 不需要转换。 operator bool 需要用户定义的转换。 @doctorlove 完美主义ftw!完成:-) 只是一个问题:使用operator bool() 真的有意义吗?这可能是最常见的运算符重载滥用之一(包括在std::ios_base 中);一个成员函数isValid(),或者其他的,要清楚得多。 【参考方案1】:

它将使用operator!

将优先选择参数类型与实参匹配的函数,而不是需要类型转换的函数。

【讨论】:

【参考方案2】:

您会发现operator ! 被执行,因为它是最直接的解决方案。如果它使用 operator bool 代替,那么它必须先调用转换运算符,然后将 ! 单独应用于该运算符。

一般来说,避免这种情况是个好主意。通常最好只定义bool 转换,因为严格来说这是您希望逻辑运算符执行的操作,而不是直接使用MyClass。定义这两者会产生一些可读性问题,并且是一种冗余代码重复形式(将来可能导致程序员错误)。

【讨论】:

我不同意您在上一部分中描述的冗余。 operator bool() 是一个转换运算符。所以像bool myTest = myObject; 这样没有operator bool() 的声明是行不通的。 我想你误解了我的意思。我的意思是定义operator bool operator ! 实际上是代码重复,因为您在不必要地复制相同(尽管是倒置的)逻辑。

以上是关于当一个对象同时提供 `operator!` 和 `operator bool` 时,这在表达式 `!obj` 中使用?的主要内容,如果未能解决你的问题,请参考以下文章

引用还是指针?

NO.10: 在operator=中处理 "自我赋值"

airflow Operators

operator.itemgetter函数

Operation Queue

第10课 面向对象的增强(default/deleteoverride/final)