在C ++中,假设C
是一个带有构造函数的类。通过
c
的实例C
时
C c = C(args);
=
是否会调用一个复制构造函数,它将C(args)
的返回作为参数,对构造函数的调用?
或者=
是否不调用复制构造函数,而是将名称c
与C(args)
的返回对象相关联?
感谢。
答案 0 :(得分:4)
可以调用复制构造函数,但也可以在C ++ 14及更早版本中对其进行优化(也称为“复制省略”)。但是在C ++ 17中,保证了这一点。
C ++ 17和先前标准之间的区别在于即使复制ctor调用在C ++ 14及更早版本中被省略,它仍然必须存在,即使它没有被调用。这是一个例子:
struct C {
C(int) { }
C(const C&) = delete;
};
int main()
{
C c = C(1);
}
在C ++ 17中,这将编译。在C ++ 14及更早版本中,它不会。尽管编译器也可能在C ++ 14中忽略了复制ctor,但是不允许它接受代码。由于C ++ 17保证了省略,因此不需要存在复制文件。
请注意,这与移动语义无关。 C c = C(1)
不会将临时转移到c
。我们也可以删除移动构造函数:
struct C {
C(int) { }
C(C&&) = delete;
C(const C&) = delete;
};
它仍然在C ++中编译17。这是省略,而不是移动操作。
此处也没有作业。在声明中,不会调用赋值运算符。但我们可以偏执并删除那些也是好的措施(赋值运算符和移动赋值运算符):
struct C {
C(int) { }
C(C&&) = delete;
C(const C&) = delete;
C& operator=(const C&) = delete;
C& operator=(C&&) = delete;
};
它仍将在C ++ 17中编译。