假设我按如下方式定义类3
:
Box
显然class Box {
public:
Box(int volume) : m_volume(volume) {}
private:
int m_volume;
};
没有定义无参数构造函数。但是,以下代码仍将编译:
Box
我认为上面的语句1)使用无参数构造函数创建了一个Box box = Box(1);
对象; 2)使用Box
构造函数创建了一个Box
对象; 3)使用默认的复制赋值运算符将Box(int)
设置为等于先前创建的box
对象。如果这个推理是正确的,代码将无法编译,因为步骤1无法执行。
那是怎么回事?
答案 0 :(得分:11)
那是怎么回事?
你错了。 :)
我认为上面的语句1)使用无参数构造函数创建了一个Box对象; 2)使用Box(int)构造函数创建Box对象; 3)使用默认的复制赋值运算符将框设置为等于先前创建的Box对象。
没有。它确实(2)然后使用临时作为其参数来复制构造命名对象。†这里根本没有赋值。
代码相当于更清晰:
Box box{Box(1)};
equals-syntax基本上是为了熟悉而提供的,因为我们传统上使用=
初始化内置函数,即使这不是“赋值”。
这就是为什么有些人不这样做的原因:
int i = 42;
但改为:
int i(42);
或者这个:
int i{42};
(我们会忽略撰写auto i = int(42)
或auto i{int(42)}
的傻瓜。)
当然,实际上你应该写作:
Box box(1);
†复制构造实际上可以被编译器“优化”掉,产生的代码实际上只相当于Box box(1)
;但是,无论如何都要求复制结构。