副本初始化是否与副本的副本初始化相同?
Is copy initialization identical to copy initialization of a copy?
以下两个代码段介绍了将变量 b
初始化为 a
的副本的任务。第一个代码段使用 copy initialization 初始化变量(初始化使用 =
)。假设 class Apple
被简单地定义为空 class:class Apple {};
Apple a;
Apple b = a;
第二个代码段也使用复制初始化来初始化变量。虽然初始化时拷贝的是a
.
的拷贝
Apple a;
Apple b = Apple(a);
盲目阅读时,似乎在 Apple(a)
处出现了一个副本,在 Apple b = ...
处出现了另一个副本。矛盾的是,覆盖 Apple
的复制构造函数以在副本上打印某些内容表明在 Apple b = Apple(a)
.
期间只发生了一个副本
Apple b = a;
和Apple b = Apple(a);
这两个语句是否相同?是否存在不相同的情况?
是的,在概念上,对于Apple b = Apple(a);
,首先从a
构造一个临时Apple
,然后从临时复制初始化b
。因为 copy elision,效果 b
直接从 a
初始化。
Under the following circumstances, the compilers are required to omit the copy and move construction of class objects, even if the copy/move constructor and the destructor have observable side-effects. The objects are constructed directly into the storage where they would otherwise be copied/moved to. The copy/move constructors need not be present or accessible:
- In the initialization of an object, when the initializer expression is a prvalue of the same class type (ignoring cv-qualification) as the variable type:
这种复制省略从C++17开始是有保证的,在C++17之前是一种优化。使用 C++17 之前的模式和禁止优化的选项进行编译,您可能会看到这两种情况之间的区别。
以下两个代码段介绍了将变量 b
初始化为 a
的副本的任务。第一个代码段使用 copy initialization 初始化变量(初始化使用 =
)。假设 class Apple
被简单地定义为空 class:class Apple {};
Apple a;
Apple b = a;
第二个代码段也使用复制初始化来初始化变量。虽然初始化时拷贝的是a
.
Apple a;
Apple b = Apple(a);
盲目阅读时,似乎在 Apple(a)
处出现了一个副本,在 Apple b = ...
处出现了另一个副本。矛盾的是,覆盖 Apple
的复制构造函数以在副本上打印某些内容表明在 Apple b = Apple(a)
.
Apple b = a;
和Apple b = Apple(a);
这两个语句是否相同?是否存在不相同的情况?
是的,在概念上,对于Apple b = Apple(a);
,首先从a
构造一个临时Apple
,然后从临时复制初始化b
。因为 copy elision,效果 b
直接从 a
初始化。
Under the following circumstances, the compilers are required to omit the copy and move construction of class objects, even if the copy/move constructor and the destructor have observable side-effects. The objects are constructed directly into the storage where they would otherwise be copied/moved to. The copy/move constructors need not be present or accessible:
- In the initialization of an object, when the initializer expression is a prvalue of the same class type (ignoring cv-qualification) as the variable type:
这种复制省略从C++17开始是有保证的,在C++17之前是一种优化。使用 C++17 之前的模式和禁止优化的选项进行编译,您可能会看到这两种情况之间的区别。