Вы можете явно вызывать конструкторы в неинициализированном хранилище с помощью оператора размещения new
, как вы упоминали.Вы можете вернуть хранилище объекта в неинициализированное состояние, явно вызвав его деструктор.
Вот простая реализация оператора присваивания, который явно вызывает конструктор копирования и деструктор, который вы уже определили как часть вашего интерфейса:
#include <new>
potato& potato::operator=(const potato& x)
{
if ( this != &x ) { // check for self-assignment!
this->~potato();
new(this) potato(x);
}
return *this;
}
Возможно, вы также захотите определить конструктор перемещения и перегрузить оператор присваивания, когда правая часть является временной.То есть перегрузка для potato&& src
, а также const potato& src
.Вы можете использовать идиому подкачки, если ваш класс поддерживает его, или тот же код, что и выше, но вызывать new(this) potato(std::move(src));
.
Если у вас есть доступ к деструктору и конструктору копирования класса, заключенному в умный указатель,вы можете сделать то же самое с ними, просто разыменовывая умные указатели.Вы, вероятно, не хотите, однако.
Конструктор копирования по умолчанию и оператор присваивания должны работать очень хорошо, если содержимое класса - умные указатели, контейнеры STL и так далее.Возможно, вы захотите скопировать данные, на которые ссылаются умные указатели, написав такие вещи, как *p = x
или *p = *q
или std::swap
, а не явные вызовы конструктора копирования.