Подтвердить что ты не робот

Вызов оператора присваивания в конструкторе копирования

Есть ли некоторые недостатки такой реализации copy-constructor?

Foo::Foo(const Foo& i_foo)
{
   *this = i_foo;
}

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

4b9b3361

Ответ 1

Да, это плохая идея. Сначала будут инициализированы все переменные-члены пользовательских типов, а затем сразу же будут перезаписаны.

Этот своп-трюк таков:

Foo& operator=(Foo rhs) // note the copying
{
   rhs.swap(*this); //swap our internals with the copy of rhs
   return *this;
} // rhs, now containing our old internals, will be deleted 

Ответ 2

В вашем конструкторе есть как потенциальные недостатки, так и потенциальные выгоды от вызова operator=().

Недостатки:

  • Ваш конструктор будет инициализировать все переменные-члены независимо от того, задаете ли вы значения или нет, а затем operator= снова инициализирует их. Это увеличивает сложность выполнения. Вам нужно будет принять разумные решения о том, когда это создаст неприемлемое поведение в вашем коде.

  • Ваш конструктор и operator= становятся плотно связанными. Все, что вам нужно сделать при создании объекта, также будет выполнено при копировании вашего объекта. Опять же, вы должны быть умны в определении того, является ли это проблемой.

Доходы:

  • Кодовая база становится менее сложной и удобной в обслуживании. Еще раз подумайте об оценке этого выигрыша. Если у вас есть структура с 2 членами строки, это, вероятно, не стоит. С другой стороны, если у вас есть класс с 50 членами данных (вы, вероятно, не должны, но это история для другого сообщения) или данных, которые имеют сложное отношение друг к другу, может быть много пользы, имея только один init вместо двух или более.