2012-06-27 2 views
3
class A {}; 
class B { public: B (A a) {} }; 

A a; 
B b=a; 

Технически говоря, применяется ли здесь экземпляр-копия при создании b?Является ли это конструктором копирования?

+5

Это не копия конструктора. Конструктор копирования принимает тот же тип объекта, что и параметр. –

+1

[Есть ли разница в C++ между инициализацией копирования и прямой инициализацией?] (Http://stackoverflow.com/questions/1051379/is-there-a-difference-in-c-between-copy-initialization-and-direct -initializati). –

ответ

7

Технически говоря, конструктор копирования применяется здесь, на создание б?

Да ... но, вероятно, не так, как вы думаете. Конструктор копий A вызывается при создании b, чтобы выполнить прохождение значения параметра A a в качестве параметра для конструктора B.

Однако, он не работает конструктор копии B в создании b.


EDIT: Один узнает что-то новое каждый день. По-видимому, даже более-технически говорящий, как заметил @CharlesBailey ... если вы используете синтаксис B b = a; («инициализация копирования») вместо синтаксиса B b (a); («прямая инициализация»), временное значение типа B может необходимо быть создан. На этом этапе конструктор копий Б закончится.

Это немного трудно изучить этот феномен, но Чарльз указывает на то, что GCC имеет -fno-elide-constructors вариант (также: Wikipedia on Copy Elision) @ ссылка JesseGood имеет исчерпывающее объяснение и некоторые демонстрационный код:

Is there a difference in C++ between copy initialization and direct initialization?

+3

Технически 'B b = a;' эквивалентен на 'B b (B (a))', поэтому неявно созданный конструктор копий B также вызывается. :) – GManNickG

+2

@GManNickG Я не понимаю, почему, видя, как B имеет конструктор преобразования от A напрямую ... –

+0

@GManNickG Действительно? Я всегда думал, что «B b = a;» был преобразован в «B b (a);», и я просто был странным, не желая иметь знак '=' в моих инициализаторах (никогда не думал, что перегружен назначение будет применимо там). Если то, что вы говорите, верно, это будет еще лучшая причина использовать форму в скобках, всегда! – HostileFork

3

Нет, конструктор копирования ссылается на объект того же типа.

03 12,1 C++ Конструкторы

  1. конструктор копирования для класса X является конструктором с первым параметром типа X& или const X&.

EDIT: Хорошо, чтобы быть справедливыми (и после прочтения других ответов), копии конструктора вызываются, но это A конструктора копирования. Я думал, ты имеешь в виду B.

EDIT2: Чтобы быть справедливым, это не является необходимым для того, чтобы назвать вообще:

A a; 
B b = a; //called 
B c = A(); //probably not called due to copy elision 
+1

Редактирование сообщения: Технически вызывается как конструкторы копирования 'A', так и' B'. При преобразовании 'a' в' B' будет создан конструктор копирования для 'A', чтобы построить параметр by-value для' B (A) ', тогда будет создан конструктор копии B' для построения 'b 'из временного' B', построенного из 'a'. –

+0

@CharlesBailey что? ничего себе не знал. Что, если бы у нас была «B (A & a)» вместо? –

+0

Затем 'a' связывается непосредственно с эталонным параметром' B (A &) '(копировать' a' не разрешается), и вызывается только конструктор копии 'B'. –

14

Да , в теории. Это копия-инициализация. Сначала создается временный экземпляр B из инициализатора (a), тогда b инициализируется из этого временного с помощью конструктора копирования.

Составители допускаются и часто делают исключение из временной и конструкции копирования, хотя и строят b непосредственно с a с использованием конструктора B(A).

+1

+1 только правильный ответ до сих пор.Я также всегда думал, что '=' -инициализация эквивалентна соответствующему вызову конструктора, пока я не попытаюсь выполнить 'std :: auto_ptr p = new T;' и не получил ожидаемых результатов. Кстати, соответствующая часть в стандарте - это пункт 8.5 [dcl.init], пункт 16. –

0

Номер не a Копировальный конструктор.

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

A a; 
A b=a; 

Приведенный выше код является экземпляром Constructor.

Смежные вопросы