2014-11-07 5 views
1

Я понимаю необходимость в глубоких копиях и для обеспечения того, что мой код ведет себя по своему желанию, я пишу экземпляр ctor, оператор присваивания и dtor для моего класса.Копировальный конструктор, оператор присваивания и дублирование кода деструктора

Однако мне кажется, что в каждом случае оператор присваивания должен сначала выполнить то, что делает деструктор (освободить любую динамически выделенную память, предотвратить утечку памяти), а затем то, что делает конструктор копирования (сделать глубокие копии всех динамически распределенных данных и скопировать их в создаваемый экземпляр).

Есть ли случай, когда оператор присваивания должен концептуально делать что-то другое, кроме следующего?

class SomeClass{ 
    //member data, copy ctor, dtor 
    SomeClass& operator=(SomeClass const& rhs){ 
     //what the destructor does 
     //what the copy constructor does 
    } 
}; 

код практически идентичен, и кажется, что это пустая трата времени, чтобы перезаписать. Кроме вызова деструктора непосредственно в начале оператора присваивания, я не могу придумать способ повторного использования кода конструктора копирования я уже написал, так как я считаю, делать что-то вроде

*this=rhs 

бы только рекурсивно вызывать оператор присваивания, так как технически «это» уже построено.

+3

Я думаю, что это, вероятно, ответит на все ваши вопросы: [Что такое копирование и своп?] (Http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom) – Barry

+0

Он также кратко освещен в разделе [C++ - faq] (http://www.parashift.com/c++-faq/assignment-operators.html) о самоопределении. См. Также [Правило трех] (https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). Комментарий эха @ JohnDibling см. В [Правило нуля] (http://flamingdangerzone.com/cxx11/2012/08/15/rule-of-zero.html). –

+1

В идеале, в хорошо продуманном классе вам не понадобится конструктор, оператор копирования или деструктор вообще. Если вам не нужен виртуальный деструктор, но даже тогда это должно быть тривиально. –

ответ

1

Как уже упоминалось в комментариях, ваши опасения по поводу дублирования кода решается путем применения copy-and-swap idiom:

class SomeClass{ 
    //member data, copy ctor, dtor 
    SomeClass& operator=(SomeClass rhs){ 
     swap(*this, rhs); 
     return *this; 
    } 
    friend void swap(SomeClass& first, SomeClass& second) { 
     using std::swap;  
     swap(first.data, second.data); 
     //... etc. for other data members 
    } 
}; 

Вы должны выполнить дополнительную swap функцию, но ваш конструктор копирования и код деструктор повторно в естественном путь. Конструктор копирования используется, когда источник присваивания передается оператору присваивания, а деструктор используется повторно, когда аргумент разрушается, когда возвращается оператор присваивания.

Смежные вопросы