Разница между двумя способами объявления объекта в стеке - PullRequest
2 голосов
/ 19 ноября 2011

В чем разница между следующими двумя объявлениями, при условии, что я не указал конструктор копирования и operator= в классе Beatle?

Beatle john(paul);

и

Beatle john = paul;

Редактировать:

При назначении объектов оператор = неявно вызывает конструктор копирования, если не указано иное?

Ответы [ 2 ]

7 голосов
/ 19 ноября 2011

Это разные грамматические конструкции. Первый - прямая инициализация , второй - копирование инициализации . Они ведут себя практически одинаково, только для второго требуется не explicit конструктор. *

Ни один из них не имеет ничего общего с оператором присваивания, так как обе строки инициализации .

То есть: const int i = 4; хорошо, а const int i; i = 4; нет.

*) Точнее: вторая версия не работает, если объявлен соответствующий конструктор explicit. В целом, таким образом, прямая инициализация дает вам одно «бесплатное» преобразование:

struct Foo { Foo(std::string) {} };

Foo x("abc");  // OK: char(&)[4] -> const char * -> std::string -> Foo
Foo y = "abd"; // Error: no one-step implicit conversion of UDTs

Чтобы обратиться к редактированию: Чтобы понять оператор присваивания, просто разбейте его на части. Предположим, что Foo имеет очевидное operator=(const Foo & rhs). Мы можем сказать x = y;, который просто вызывает оператора напрямую с rhs, равным y. Теперь рассмотрим это:

x = "abc";              // error, no one-step implicit conversion
x = std::string("abc"); // fine, uses Foo(std::string), then copy
x = Foo("abc");         // fine, implicit char(&)[4] -> const char* -> std::string, then as above
2 голосов
/ 19 ноября 2011

Во-первых, это прямая инициализация, а во-вторых, копирование инициализации.

Прямая инициализация означает, что объект инициализируется с использованием одного (возможно, преобразования) конструктора и эквивалентен форме T t(u);:

U u;
T t1(u); // calls T::T( U& ) or similar

Инициализация копирования означает, что объект инициализируется с помощью конструктора копирования после первого вызова пользовательского преобразования, если это необходимо, и эквивалентен форме T t = u;:

T t2 = t1;  // same type: calls T::T( T& ) or similar
T t3 = u;   // different type: calls T::T( T(u) )
            //  or T::T( u.operator T() ) or similar

Копировать Инициализация не работает, если объявлен конструктор explicit.

Ссылки
Эта запись в GOTW Херба Саттера должна быть хорошо прочитана.


Чтобы ответить на ваш отредактированный вопрос:
= имеет различное значение в зависимости от того, как оно используется.

Если = используется в выражении, в котором объект создается и инициализируется одновременно, то = рассматривается не как оператор присваивания, а как инициализация копирования.

Если = используется для назначения одного объекта другому, после того, как объект был создан, это приводит к вызову оператора присваивания.

...