Два объявления
Example example2 = Example(5);
Example example3(5);
эквивалентны.Хотя первый выглядит так, как будто он может создать объект и затем вызвать конструктор копирования, большинство компиляторов просто создают на месте объект example2
.
Решение о том, когда выбирать, какойиспользование перечисленных выше стилей в значительной степени зависит от вкуса.
Вот полный пример программы для демонстрации:
#include <iostream>
using namespace std;
class Test {
public:
Test(int x): X(x) {
cout << "constructor " << X << endl;
}
Test(const Test &rhs): X(rhs.X) {
cout << "copy " << X << endl;
}
Test &operator=(const Test &rhs) {
X = rhs.X;
cout << "assign " << X << endl;
return *this;
}
private:
int X;
};
int main()
{
Test t1 = Test(1);
Test t2(2);
t2 = t1;
}
и вывод (gcc 4.2.1, OS X Lion):
constructor 1
constructor 2
assign 1
Обратите внимание, как оператор присваивания вызывается только для t2 = t1
(как и ожидалось), но конструктор копирования вообще не вызывается.(Однако, как отмечает Деннис Зиккефуз в комментариях, конструктор копирования должен быть доступен . Попробуйте сделать конструктор копирования private
в приведенном выше примере, и компилятор должен отказаться от его компиляции.)
РЕДАКТИРОВАТЬ: Обратите внимание, что gcc
на самом деле имеет параметр, который контролирует это поведение:
-fno-elide-constructors
The C++ standard allows an implementation to omit creating a
temporary which is only used to initialize another object of the
same type. Specifying this option disables that optimization, and
forces G++ to call the copy constructor in all cases.