为什么在分配之前有副本?

时间:2012-03-21 14:18:39

标签: c++

我正在做以下测试:

#include <iostream>
#include <vector>

using namespace std;
class A
{
private:
   int i;
public:
   A():i(1){cout<<"A constr"<<endl;}
   A(const A & a):i(a.i){cout<<"A copy"<<endl;}
   virtual ~A(){cout<<"destruct A"<<endl;}
   void operator=(const A a){cout<<"A assign"<<endl;}
};


int main()
{
   A o1; 
   A o2; 
   o2=o1;
}

输出是:

A constr
A constr
A copy
A assign
destruct A
destruct A
destruct A

似乎“o2 = o1”先完成了一个副本,然后是一个任务,我想知道它背后的故事是什么。谢谢!

2 个答案:

答案 0 :(得分:15)

因为您将值传递给赋值运算符:

void operator=(const A a)

您可能希望通过引用传递,并且还应该返回对assign-to对象的引用:

A& operator=(const A& a) { std::cout << "A assign" << std::endl; return *this; }

答案 1 :(得分:4)

您似乎设置了要正确实施的赋值运算符:

T& T::operator= (T value) {
    value. swap(*this);
    return *this;
}

参数通过副本传递给assigment运算符,编译器实际上需要在您的设置中执行此复制。如果你已经通过了一个临时的副本可以避免:

o2 = A();

因此,上面的实现实际上有一些有趣的属性:

  • 它利用已经编写的函数:复制构造函数是生成或写入但是做正确的事情,如果你想要一个作业,你可能想要swap()成员
  • 如果swap()操作非投掷,则赋值是强安全异常安全的。当分配者输入图片时,事情需要稍微不同,但
  • 该作业试图避免实际的复制操作,因为在某些情况下可以省略参数传递期间的副本,即内容只是swap()编辑到位