Присваивание через копирование

У Александреску, в “Современное проектирование на С++”, нашел следующие строки:

“… однако, к счастью, 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. Всё.

2 комментария на «Присваивание через копирование»

  1. NonMqwrlkf:

    Саттер имел в виду совсем другой способ. И вспомогательного кода в операторе (или методе swap) будет заметно больше.
    А тот, что описан здесь, череват большим количеством проблем.

  2. divercide:

    Спасибо за комментарий за 4 года :-) А я уж было и забыл про этот блог.

    Касательно обмена через swap: я в курсе, что так будет православно, но до сих пор не в курсе, каким «множеством ошибок» чревато использование деструктора?

Добавить комментарий

Fill in your details below or click an icon to log in:

Логотип WordPress.com

You are commenting using your WordPress.com account. Log Out / Изменить )

Фотография Twitter

You are commenting using your Twitter account. Log Out / Изменить )

Фотография Facebook

You are commenting using your Facebook account. Log Out / Изменить )

Connecting to %s

Follow

Get every new post delivered to your Inbox.