В C++ есть два метода, которые отвечают за копирование объектов. Они называются:

  • Конструктор копирования
  • Копировать оператор присваивания

Следующий класс имеет конструктор копирования и оператор присваивания копии:

class Polygon{
public:
//...
//Copy constructor
Polygon(const Polygon& p):name(p.name){}

//Copy assignment operator
Polygon& operator=(const Polygon& p){
name=p.name;    //copy p's data
return *this;
}
private:
std::string name;
};

В этом нет ничего нового для вас. Когда мы вызываем конструктор копирования или назначение копирования, элемент данных name копируется в новый объект.

Теперь предположим, что вы добавили в класс еще один элемент данных с именем distance.

class Polygon{
public:
//...
//Copy constructor
Polygon(const Polygon& p):name(p.name){}

//Copy assignment operator
Polygon& operator=(const Polygon& p){
name=p.name;    //copy p's data
return *this;
}
private:
std::string name;
float distance;
};

Как вы думаете, что произойдет, если вы забудете реализовать копию нового члена данных как в конструкторе копирования, так и в присваивании копии?

Да, вы правы. Член данных distance не будет скопирован. Один из советов из книги Efficient C++ — обязательно скопируйте все элементы данных объекта.

Итак, простое исправление показано ниже:

class Polygon{
public:
//...
//Copy constructor
Polygon(const Polygon& p):name(p.name),distance(p.distance){}

//Copy assignment operator
Polygon& operator=(const Polygon& p){
name=p.name;    //copy p's data
distance=p.distance;
return *this;
}
private:
std::string name;
float distance;
};

Это может показаться вам очевидным, но проблема обычно возникает при использовании производных классов. Давайте посмотрим, что происходит, когда у вас есть производный класс и вы реализуете конструктор копирования и присваивание копии.

class Triangle:Polygon{
public:
//...
//Copy constructor
Triangle(const Triangle& t):coordinate(t.coordinate){}

//Copy assignment operator
Triangle& operator=(const Triangle& t){
coordinate=t.coordinate;    //copy t's data
return *this;
}
private:
float coordinate
};

Когда вы делаете копию своего производного класса, элементы данных из базового класса не будут скопированы!!! Вы обязаны сообщить методам копирования, чтобы они также копировали конструктор копирования и присваивание базового класса. Это делается следующим образом:

class Triangle:Polygon{
public:
//...
//In the copy constructor invoke the base class copy constructor
Triangle(const Triangle& t):Polygon(t),coordinate(t.coordinate){}

//Copy assignment operator
Triangle& operator=(const Triangle& t){
//inform the base class to copy its data members
Polygon::operator=(t);
coordinate=t.coordinate;    //copy t's data
return *this;
}
private:
float coordinate
};

Я надеюсь, что этот совет будет полезен.

Получите больше советов по разработке на haroldserrano.com