Classes and class hierarchies
C.61
Операция копирования должна копировать
Причина
Это общепринятая семантика. После x = y мы должны иметь x == y. После копирования x и y могут быть независимыми объектами (семантика значения, как встроенные типы, отличные от указателей, и типы стандартной библиотеки) или ссылаться на общий объект (семантика указателя, как работают указатели).
Пример
class X { // OK: value semantics
public:
X();
X(const X&); // copy X
void modify(); // change the value of X
// ...
~X() { delete[] p; }
private:
T* p;
int sz;
};
bool operator==(const X& a, const X& b)
{
return a.sz == b.sz && equal(a.p, a.p + a.sz, b.p, b.p + b.sz);
}
X::X(const X& a)
:p{new T[a.sz]}, sz{a.sz}
{
copy(a.p, a.p + sz, p);
}
X x;
X y = x;
if (x != y) throw Bad{};
x.modify();
if (x == y) throw Bad{}; // assume value semantics
Пример
class X2 { // OK: pointer semantics
public:
X2();
X2(const X2&) = default; // shallow copy
~X2() = default;
void modify(); // change the pointed-to value
// ...
private:
T* p;
int sz;
};
bool operator==(const X2& a, const X2& b)
{
return a.sz == b.sz && a.p == b.p;
}
X2 x;
X2 y = x;
if (x != y) throw Bad{};
x.modify();
if (x != y) throw Bad{}; // assume pointer semantics
Примечание
Предпочитайте семантику значения, если только вы не строите «умный указатель». Семантика значения — это самая простая для рассуждения и то, что ожидают средства стандартной библиотеки.
Применение
(Не применимо)