Многие классы имеют оператор присваивания (operator =) того же кода, что и в деструкторе, и очень похожий код конструктора копирования.
Так это хорошая идея, чтобы выполнить задание таким образом?
Point& operator=(const Point& point)
{
if(&point != this)
{
//Call the destructor
this->~Point();
//Make the placement new
//Assignment is made because some compilers optimise such code as just
// new Point;
Point* p_n = new (this) Point(point);
//We where placing in this place so pointers should be equal
assert(p_n == this);
}
return *this;
}
Херб Саттер обратился к этому в одна из его статей GotW. Я рекомендую вам прочитать это. Его вывод:
Оригинальная идиома полна ловушек, она часто ошибочна, и это делает
жизнь адом для авторов производных классов. Я иногда
соблазн выложить вышеуказанный код на офисную кухню с подписью:
«Здесь будут драконы».Из стандартов кодирования GotW:
предпочесть написание общей частной функции для совместного использования кода между копированием и назначением копирования, если это необходимо; никогда не используйте хитрость
реализация копирования копии с точки зрения построения копии с использованием
явный деструктор с последующим размещением нового, хотя этот трюк
всплывает каждые три месяца в группах новостей (то есть никогда не пишите:T& T::operator=( const T& other ) { if( this != &other) { this->~T(); // evil new (this) T( other ); // evil } return *this; }
Нет. Это плохая идея, хотя стандарт C ++ использует такие вещи в качестве примера при обсуждении времени жизни объекта. Для типа значения как Point
это не так уж плохо, но если вы наследуете от этого класса, эта реализация присваивания изменит тип объекта с вашего производного типа на Point
; если задействованы виртуальные функции, вы увидите резкое изменение в поведении.