Вызов оператора присваивания в конструкторе копирования
Есть ли некоторые недостатки такой реализации copy-constructor?
Foo::Foo(const Foo& i_foo)
{
*this = i_foo;
}
Как я помню, в какой-то книге было рекомендовано вызвать конструктор копирования из оператора присваивания и использовать хорошо известный своп-трюк, но я не помню, почему...
Ответы
Ответ 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 вместо двух или более.
Ответ 3
Вы ищете Эффективный С++ Скотта Мейерса. Пункт 12: Скопируйте все части объекта.