В 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