Рассмотрим класс, копии которого необходимо сделать. Подавляющее большинство элементов данных в копии должны строго отражать оригинал, однако есть несколько элементов, состояние которых не должно сохраняться и нуждается в повторной инициализации.
Является ли плохая форма вызовом оператора присваивания по умолчанию из конструктора копирования?
Оператор присваивания по умолчанию будет хорошо вести себя с обычными старыми данными (int, double, char, short), а также определенными пользователем классами на их операторы присваивания. Указатели должны рассматриваться отдельно.
Один из недостатков заключается в том, что этот метод приводит к тому, что оператор присваивания искалечен, поскольку дополнительная повторная инициализация не выполняется. Также невозможно отключить использование оператора присваивания, тем самым открыв пользователю возможность создать сломанный класс, используя неполный оператор присваивания по умолчанию A obj1,obj2; obj2=obj1; /* Could result is an incorrectly initialized obj2 */
.
Было бы неплохо смягчить требование, чтобы в a(orig.a),b(orig.b)...
в дополнение к a(0),b(0) ...
нужно было записать. Необходимость записи всей инициализации дважды создает два места для ошибок, и если в класс должны быть добавлены новые переменные (например, double x,y,z
), код инициализации должен быть правильно добавлен как минимум в 2 места вместо 1.
Есть ли лучший способ?
Есть ли лучший способ в С++ 0x?
class A {
public:
A(): a(0),b(0),c(0),d(0)
A(const A & orig){
*this = orig; /* <----- is this "bad"? */
c = int();
}
public:
int a,b,c,d;
};
A X;
X.a = 123;
X.b = 456;
X.c = 789;
X.d = 987;
A Y(X);
printf("X: %d %d %d %d\n",X.a,X.b,X.c,X.d);
printf("Y: %d %d %d %d\n",Y.a,Y.b,Y.c,Y.d);
Вывод:
X: 123 456 789 987
Y: 123 456 0 987
Альтернативный конструктор копирования:
A(const A & orig):a(orig.a),b(orig.b),c(0),d(orig.d){} /* <-- is this "better"? */