在深度复制期间,我们正在编写重载的复制构造函数和赋值运算符。 我可以知道为什么我们必须编写重载的赋值运算符,因为我们在重载的复制构造函数中做了同样的事情(除了一些检查并返回它)。
谁在调用赋值运算符
答案 0 :(得分:5)
按照 Rule of Three :
如果您需要为您的班级编写复制构造函数,您还应该编写复制赋值运算符和析构函数。
复制分配运算符和复制构造函数都称为复制函数。它们基本上有助于从现有对象获取对象的新副本。它们都是在不同场景中调用的独立实体。因此,就像复制构造函数一样,您确保对所有指针成员进行深度复制,而不仅仅是浅复制,同样适用于复制赋值运算符。
代码示例:
class MyClass obj1, obj2;
class MyClass obj3(obj1); //Calls Copy Constructor
obj1 = obj2; //Calls Copy Assignment Operator
答案 1 :(得分:2)
如果您执行此操作,则使用赋值运算符:
MyType my1, my2;
my1 = my2; // same as: my1.operator=(my2);
答案 2 :(得分:0)
复制构造函数和赋值运算符通常具有非常相似的代码,但如果正确完成(初始化列表),则应采用不同的编码,使用方式不同,执行方式不同。
复制构造函数应该使用初始化列表。这用于创建一个与已存在的对象相同的新矢量对象。
vector::vector(const vector& b)
:size(b.size),
capacity(b.capacity),
data(new TYPE[size])
{
//there should be minimal code here
//I'm skipping copying the data, because doing it right
//is hard and beside the point
}
vector seven;
seven.push_back(7);
vector seven_copy(seven); //make a new one, same as old
赋值运算符可能就是你所拥有的。这用于重新分配已存在的矢量对象与现有的矢量对象相同
vector& vector::operator=(const vector& b)
{
//carefully written so self assignment doesn't crash.
TYPE* temp = new TYPE[b.size];
//I'm skipping copying the data, because doing it right
//is hard and beside the point
delete [] data;
//all exceptions that can be thrown, have, so it's safe to modify members now
data = temp;
size = b.size;
capacity = b.capacity;
return *this;
}
vector nine;
nine.push_back(9);
nine = seven; //make an old one the same as another old
应该注意的是,移动构造函数和移动赋值可能看起来有点类似,但也应该是不同的。
vector::vector(vector&& b)
:size(b.size)
capacity(b.capacity)
data(b.data) //different!
{
b.data = nullptr;
}
vector& operator=(vector&& b)
{
//since b.data is tied to b.size and b.capacity, it's safest to just swap
//so if someone calls b.push_back() after, it's all still safe.
std::swap(size, b.size);
std::swap(capacity, b.capacity);
std::data(data, b.data);
return *this;
}