在临时对象上复制构造函数
copy constructor c++ on temporary objects
#include <iostream>
using namespace std;
class A
{
int x;
public:
A(int c) : x(c) {}
A(const A& a) { x = a.x; cout << "copy constructor called" << endl;}
};
class B
{
A a;
public:
B(int c) : a(c) {}
B(const B& b) : a(b.a) { }
A get_A() { return a;}
};
int main()
{
B b(10);
A a1 = b.get_A();
}
在上面的代码中,我期望'copy constructor called'消息会弹出两次,因为首先,b.t get_a()将创建一个临时对象来调用复制构造函数(1),其次,它将其引用复制到a1的复制构造函数(2),从而显示两条消息。
然而,这段代码实际上产生了一个名为"复制构造函数"的消息。为什么?
c++标准允许在某些情况下省略复制构造函数。通常,这意味着如果对象将从临时变量复制构造。可以就地构造。
在这种情况下,get_A();
返回了一个副本到临时。然后将a1
赋值给该临时变量。编译器允许省略多余的副本,并使用get_A()
的返回值来构造a1
。
即使复制构造函数有副作用,也可以进行这种优化。
复制省略是唯一可以改变可观察到的副作用的优化形式。因为有些编译器并不是在允许的所有情况下都执行拷贝省略,所以依赖于拷贝/移动构造函数和析构函数副作用的程序是不可移植的。
在c++ 11中,代码可能会调用move构造函数来移动对象而不是复制对象,或者在c++ 03和c++ 11中,以NRVO形式的编译器优化可能会应用copy省略来省略副本。
注意,后者(复制省略)取决于编译器的能力,不保证,而前者(移动语义)在c++ 11中是保证的。
相关文章:
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 使用复制构造函数复制双精度数组
- C 无可行的构造函数复制类型的变量
- 没有可行的构造函数复制类型 'MyString' 的数组元素
- 编译时,复制构造函数/复制分配和正常功能调用优化之间是否存在任何区别
- 如何最小化调用列表构造函数(复制构造函数)的次数?
- C 11矢量构造函数复制与范围
- 我定义了一个非复制构造函数;复制构造函数还会被隐式定义吗
- 可以将构造函数复制为转换运算符
- 将基类指针的构造函数复制到子类
- C++树类:构造函数/复制/内存泄漏
- 如何制作这个在模板构造函数复制中使用类型定义的类型的模板
- 将构造函数复制为模板化的成员函数
- 绕过私有复制构造函数/复制赋值C++
- C++通过构造函数复制对象
- 复制构造函数 - 复制C++中的对象
- 将带unique_ptr的类的构造函数复制到作为成员的抽象类