Вот выдержка из пункта 56 книги "C ++ Gotchas":
Нередко можно увидеть простой
написана инициализация объекта Y
любой из трех разных способов, как будто
они были эквивалентны.
Y a( 1066 );
Y b = Y(1066);
Y c = 1066;
На самом деле, все три из них
инициализация, вероятно, приведет
в том же объектном коде, являющемся
генерируется, но они не эквивалентны.
Инициализация известна как
прямая инициализация, и это делает
именно то, что можно ожидать.
инициализация осуществляется через
прямой вызов Y :: Y (int).
Инициализация b и c
более сложный. На самом деле, они тоже
сложный. Это оба копии
инициализация. В случае с
инициализация б, мы запрашиваем
создание анонимного временного
типа Y, инициализируется значением
1066. Затем мы используем этот анонимный временный как параметр для копии
конструктор для класса Y для инициализации
б. Наконец, мы вызываем деструктор для
анонимный временный.
Чтобы проверить это, я сделал простой класс с элементом данных (программа прикреплена в конце), и результаты оказались удивительными. Похоже, что для случая 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. Чтобы быть точным, я ожидал, что будет создан пустой объект, а затем объект, который будет создан и назначен для пустого объекта. На практике объекты были созданы конструктором копирования.