复制构造函数和赋值运算符
Posted
技术标签:
【中文标题】复制构造函数和赋值运算符【英文标题】:The copy constructor and assignment operator 【发布时间】:2011-07-19 02:28:44 【问题描述】:如果我覆盖operator=
,复制构造函数会自动使用new 运算符吗?同样,如果我定义了一个拷贝构造函数,operator=
会自动“继承”拷贝构造函数的行为吗?
【问题讨论】:
看看这个链接:***.com/questions/1457842/… & ***.com/questions/1477145/… What is The Rule of Three?的可能重复 【参考方案1】:不,它们是不同的运算符。
复制构造函数用于创建一个新对象。它将现有对象复制到新构造的对象。复制构造函数用于从旧实例初始化新实例 实例。将变量按值传递给函数时不一定会调用它 或作为函数的返回值。
赋值运算符是处理一个已经存在的对象。赋值运算符用于将现有实例更改为 与右值相同的值,这意味着实例必须是 如果它有内部动态内存,则销毁并重新初始化。
有用的链接:
Copy Constructors, Assignment Operators, and More Copy constructor and = operator overload in C++: is a common function possible?【讨论】:
...is called when passing variables by value into functions or as return values out of functions.
不一定。由于 RVO,当您按值返回时,可能不会调用复制构造函数。
@PS:+1 ...谢谢!已编辑!
@Prasoon,我不太明白,当按值将变量传递给函数或作为函数的返回值时,为什么不能调用复制构造函数?什么是 RVO?
@Alcottreturn 值优化
还有复制省略,对函数参数也是如此【参考方案2】:
没有。除非您定义复制 ctor,否则将生成默认值(如果需要)。除非您定义 operator=,否则将生成默认值(如果需要)。它们不相互使用,您可以独立更改它们。
【讨论】:
【参考方案3】:没有。它们是不同的对象。
如果您担心复制构造函数和赋值运算符之间的代码重复,请考虑以下成语,命名为 copy and swap:
struct MyClass
MyClass(const MyClass&); // Implement copy logic here
void swap(MyClass&) throw(); // Implement a lightweight swap here (eg. swap pointers)
MyClass& operator=(MyClass x)
x.swap(*this);
return *this;
;
这样,operator=
将使用复制构造函数来构建一个新对象,该对象将与*this
交换并在函数退出时释放(其中包含旧的this
)。
【讨论】:
通过引用 copy-and-swap 习语,您是否暗示在 copy-ctor 中调用 operator= 不是一个好习惯,反之亦然? @Alcott:您不会在复制构造函数中调用 operator=,而是以相反的方式调用,就像我展示的那样。 为什么你的赋值运算符不使用 const 引用? @JohanBoule:我的回答中的***链接以及this question对此进行了解释【参考方案4】:没有。
一定要看看the rule of three (或rule of five 考虑右值)
【讨论】:
【参考方案5】:考虑以下 C++ 程序。注意:我的“Vector”类不是标准库中的那个。我的“Vector”类接口 :
#include <iostream>
class Vector
private:
double* elem; // elem points to an array of sz doubles
int sz;
public:
Vector(int s); // constructor: acquire resources
~Vector() delete[] elem; // destructor: release resources
Vector(const Vector& a); // copy constructor
Vector& operator=(const Vector& a); // copy assignment operator
double& operator[](int i) return elem[i]; ;
int size() const return sz;;
;
我的“向量”类成员实现:
Vector::Vector(int s) // non-default constructor
std::cout << "non-default constructor"<<std::endl;
elem = new double[s];
sz =s;
for (int i=0; i!=s; ++i) // initialize elements
elem[i]=0;
Vector::Vector(const Vector& a) // copy constructor
:elemnew double[a.sz],
sza.sz
std::cout << "copy constructor"<<std::endl;
for (int i=0; i!=sz; ++i) // copy elements
elem[i] = a.elem[i];
Vector& Vector::operator=(const Vector& a) // copy assignment operator
std::cout << "copy assignment operator"<<std::endl;
double* p = new double[a.sz];
for (int i=0; i!=a.sz; ++i)
p[i] = a.elem[i];
delete[] elem; // delete old elements
elem = p;
sz = a.sz;
return *this;
int main()
Vector v1(1);
v1[0] = 1024; // call non-default constructor
Vector v2 = v1; // call copy constructor !!!!
v2[0] = 1025;
std::cout << "v2[0]=" << v2[0] << std::endl;
Vector v310; // call non-default constructor
std::cout << "v3[0]=" << v3[0] << std::endl;
v3 = v2; // call copy assignment operator !!!!
std::cout << "v3[0]=" << v3[0] << std::endl;
然后,程序输出:
non-default constructor
copy constructor
v2[0]=1025
non-default constructor
v3[0]=0
copy assignment operator
v3[0]=1025
总结:
Vector v2 = v1;
导致调用复制构造函数。
v3 = v2;
导致调用复制赋值运算符。
在情况 2 中,对象 v3
已经存在(我们已经完成:Vector v310;
)。拷贝构造函数和拷贝赋值运算符有两个明显的区别。
copy construct
一个新对象。 (因为它Vector v2
)
复制构造函数不需要返回this
指针。(此外,所有构造函数都不返回值)。
【讨论】:
【参考方案6】:不,它们不是同一个运算符。
【讨论】:
以上是关于复制构造函数和赋值运算符的主要内容,如果未能解决你的问题,请参考以下文章