c – 在对象被激活之后,使用隐式转换而不是赋值运算符调用构造函数的要点是什么?

考虑下面的例子:
#include <iostream>
using std::cout;
using std::endl;

class CBox
{
public:
    CBox(double lv = 1.0,double wv = 1.0,double hv = 1.0) :
        m_Length {lv},m_Width {wv},m_Height {hv}
    {
        cout << "Constructor called" << endl;   
    }

    //CBox& operator=(double)
    //{
    //  cout << "Assignment operator called" << endl;
    //  return *this;
    //}

    double volume() const { return m_Length* m_Width* m_Height; }

private:
    double m_Length;
    double m_Width;
    double m_Height;
};

int main()
{
    CBox Box {1.0,1.0,1.0}; // no need for intializer list,but put it anyway
    Box = 2.0; // why is this calling constructor again ?!
    cout << Box.volume() << endl; // prints 2
}

请注意,我有意地注释掉了重载的赋值运算符.

执行此程序会产生以下输出

Constructor called
Constructor called
2

我注意到,即使Box对象已被初始化,下一个语句也是故意地调用构造函数.这是什么意思?

我知道这可以通过explicit关键字来防止,所以构造函数将是:

explicit CBox(double lv = 1.0,m_Height {hv}
    {
        cout << "Constructor called" << endl;   
    }

但我宁愿期望影响如下结构:

CBox Box = 2.0;

当然,当我取消注释重载的赋值运算符时,它优先于构造函数.

解决方法

没有隐含的CBox :: operator =(double),所以Box = 2.0;必须创建一个临时的CBox对象.相当于Box = CBox(2.0);.

使你的构造函数显式不允许从double转换为CBox的隐式转换,所以没有适当的赋值运算符存在,并且你得到一个编译错误.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...