重载 bool 转换和取消引用对象指针

Posted

技术标签:

【中文标题】重载 bool 转换和取消引用对象指针【英文标题】:overloaded bool conversion and dereference object pointer 【发布时间】:2021-08-01 01:09:20 【问题描述】:
class D
    bool var;
public:
    D(bool x): var(x) 
    operator bool()return var;
;

int main() 
    D* temp1 = new D(false);
    cout << *temp1;  //0

    D* temp2 = new D(true);
    cout << *temp2;  //1
    return 0;

我正在尝试重载对象 D 的 bool 转换。然后我发现重载的 bool 转换与取消引用对象指针时的值之间存在关系。

我用不同的值初始化了 2 个对象。当我尝试取消引用指针时,我看到它们返回与重载 bool 转换相同的值。 重载bool转换和解引用对象指针是什么关系?

【问题讨论】:

【参考方案1】:

您正在打印将 D 对象转换为 bool 的结果:

引用D* 会为您提供D 类型的值。 当您编写cout &lt;&lt; *temp1 时,该语言会查找operator&lt;&lt; 重载,该重载将std::ostream 作为其左侧操作数,并将D 类型的对象作为其右侧操作数。 没有这样的重载,但是一个重载,它采用bool 类型的右手操作数。 由于D 可以通过operator bool 隐式转换为bool,因此std::ostream::operator&lt;&lt;(bool) 在这种情况下被选为最佳&lt;&lt; 运算符重载。

该特定运算符将0 插入std::ostream 以获取false 值并插入1 以获取true 值(除非std::boolalpha 操纵器先前已应用于流)。因此,由于static_cast&lt;bool&gt;(*temp1)falsecout &lt;&lt; *temp1 打印0 并且因为static_cast&lt;bool&gt;(*temp2)true cout &lt;&lt; *temp2 打印1

【讨论】:

D数据类型到bool的转换是因为iostream类的实现还是编译器的机制? 两者兼而有之?这是由于标准的重载解决规则。如果编译器找不到函数调用的精确匹配,它将考虑最多一次用户定义的转换。标准库恰好有一个operator&lt;&lt; 重载,它接受一个std::ostream 和一个用于打印bools 的bool,这恰好是这种情况下的最佳匹配。您可以编写自己的 operator&lt;&lt;(std::ostream&amp;, const D&amp;) 来做任何您想做的事情,这将是 get selected as a better match。【参考方案2】:

重载bool转换和解引用对象指针有什么关系?

当你间接通过对象指针时,结果是对象的左值。当您将隐式转换运算符定义为 bool 时,该对象可转换为 bool。这就是正在发生的事情:您正在使用转换运算符,并且转换的结果作为参数传递给流插入运算符。

【讨论】:

以上是关于重载 bool 转换和取消引用对象指针的主要内容,如果未能解决你的问题,请参考以下文章

重载函数的调用匹配规则

关于函数指针的注意事项

带有引用和指针的指针的重载返回

14:操作重载和类型转换

c++中重载输出流对象,为啥要返回引用

拷贝构造,赋值运算符重载(六千字长文详解!)