У Александреску, в “Современное проектирование на С++”, нашел следующие строки:
“… однако, к счастью, Sutter (2000) описал очень остроумный способ, позволяющий реализовать оператор присваивания с помощью конструктора копирования. (Он настолько остроумен, что о нем обязательно следует прочитать. Этот способ был применен при реализации класса SmartPtr в библиотеке Loki.)”
Вот и решил узнать, как такое возможно.
Причина – банальная лень и надежда, что этот способ займет меньше строк кода.
Гугление и вопросы в irc результата не дали, поэтому пришлось выдавить из себя следующее:
Foo& Foo::operator = (const Foo& src)
{
if (this != &src)
{
this->~Foo();
new(static_cast<void*>(this)) Foo(src);
}
return *this;
}
Если используется какой-нибудь класс а-ля двусвязный список, то удобно – не надо дублировать код. Вызываем явно деструктор для объекта, которому присваиваем новое значение – в результате и деструктор вызвали, и память осталась нашей. Потом оператор new создаёт временный объект Foo(src), и копирует его по адресу указателя this. Всё.
Саттер имел в виду совсем другой способ. И вспомогательного кода в операторе (или методе swap) будет заметно больше.
А тот, что описан здесь, череват большим количеством проблем.
Спасибо за комментарий за 4 года
А я уж было и забыл про этот блог.
Касательно обмена через swap: я в курсе, что так будет православно, но до сих пор не в курсе, каким «множеством ошибок» чревато использование деструктора?