Вот выдержка из пункта 56 книги "C++ Gotchas":
Нередко можно увидеть простую инициализацию объекта Y, написанную любым из трех разных способов, как если бы они были эквивалентны.
Y a( 1066 );
Y b = Y(1066);
Y c = 1066;
На самом деле, все три эти инициализации, вероятно, приведут к созданию одного и того же объектного кода, но они не эквивалентны. Инициализация a известна как прямая инициализация, и она делает именно то, что можно было бы ожидать. Инициализация выполняется прямым вызовом Y::Y(int).
Инициализация b и c более сложна. На самом деле они слишком сложны. Это обе инициализации копирования. В случае инициализации b мы запрашиваем создание анонимного временного объекта типа Y, инициализированного значением 1066. Затем мы используем этот анонимный временный объект в качестве параметра конструктора копирования для класса Y для инициализации b. Наконец, мы вызываем деструктор для анонимного временного объекта.
Чтобы проверить это, я создал простой класс с элементом данных (программа, прикрепленная в конце), и результаты меня удивили. Кажется, что в случае c объект был создан конструктором копирования, а не так, как это предлагается в книге.
Кто-нибудь знает, изменился ли стандарт языка или это просто функция оптимизации компилятора? Я использовал Visual Studio 2008.
Пример кода:
#include <iostream>
class Widget
{
std::string name;
public:
// Constructor
Widget(std::string n) { name=n; std::cout << "Constructing Widget " << this->name << std::endl; }
// Copy constructor
Widget (const Widget& rhs) { std::cout << "Copy constructing Widget from " << rhs.name << std::endl; }
// Assignment operator
Widget& operator=(const Widget& rhs) { std::cout << "Assigning Widget from " << rhs.name << " to " << this->name << std::endl; return *this; }
};
int main(void)
{
// construct
Widget a("a");
// copy construct
Widget b(a);
// construct and assign
Widget c("c");
c = a;
// copy construct!
Widget d = a;
// construct!
Widget e = "e";
// construct and assign
Widget f = Widget("f");
return 0;
}
Выход:
Constructing Widget a
Copy constructing Widget from a
Constructing Widget c
Assigning Widget from a to c
Copy constructing Widget from a
Constructing Widget e
Constructing Widget f
Copy constructing Widget from f
Больше всего меня удивили результаты построения d и e. Чтобы быть точным, я ожидал, что будет создан пустой объект, а затем объект будет создан и назначен пустому объекту. На практике объекты создавались конструктором копирования.
Y c = 1006
невозможно, если ваш конструктор объявлен какexplicit
... как и любой конструктор с одним параметром, большую часть времени. - person Matthieu M.   schedule 17.03.2010