2012-01-08 6 views
6

Сейчас я изучаю ctors и задаю несколько вопросов. На этих линиях:Создание и создание объекта C++

Foo obj(args); 

Foo obj2; 
obj = Foo(args); 

Foo obj3 = Foo(args); 

Первая часть: только один конструктор называется (Foo) и obj инициализируется. Итак, создание одного объекта.

Вторая часть: создание временного объекта obj2, вызывающего по умолчанию для него. В последующих строках мы создаем еще одну копию Foo и передаем ее копию в operator=(). Это правильно? Итак, 3 локальных временных объекта, 2 вызова конструктора.

Третья часть: создать 1 объект Foo и передать его копию в operator=(). Итак, 2 темпоральных объекта и 1 вызов ctor.

Насколько я понимаю это право? И если это правда, будет ли компилятор (последний gcc, например) оптимизировать их в обычных случаях?

+0

'operator =()' обычно получает свой аргумент по ссылке, поэтому никаких копий при его вызове. – rodrigo

+0

obj3 фактически создан с использованием оператора копирования без назначения оператора. –

ответ

6

я прокомментирую третий первый:

Foo obj3=Foo(args); 

Он не использует operator=, который называется копией присваивания. Вместо этого он вызывает экземпляр-конструктор (теоретически). Здесь нет заданий. Таким образом, теоретически существует два объекта создания: одно временное, другое - obj3. Компилятор может оптимизировать код, полностью вернув создание временного объекта.

Теперь, второй один:

Foo obj2;   //one object creation 
obj = Foo(args); //a temporary object creation on the RHS 

Здесь первая строка создает объект, вызывая конструктор по умолчанию. Затем он вызывает operator=, передавая временный объект, созданный из выражения Foo(args). Таким образом, существует только два объекта: operator= принимает аргумент const (что и должно делать).

И что касается первого, вы правы.

+0

Хорошо, спасибо. Но в любом случае, в первом случае создается только 1 объект типа 'Foo', в третьем - 2 объекта? – Ockonal

+0

Нет, согласно спецификациям, часть 1 и часть 3 являются двумя способами указания одной и той же вещи. Нет никакой разницы в реализации. –

+2

@MrLister: Нет. Между «1» и «3» существует тонкая разница. Просто напишите тестовый код и сделайте copy-constructor 'private'. Первый будет компилироваться, третий - нет! – Nawaz

3
  1. Да, Foo obj(args) создает один объект Foo и называет ctor один раз.

  2. obj2 не считается временным объектом. Но точно так же, как 1 Foo obj2 создает один объект и вызывает Foo ctor. Предполагая, что вы имели в виду obj2 = Foo(args) для следующей строки, эта строка создает один временный объект Foo, а затем вызывает obj2.operator=(). Таким образом, для этого второго примера существует только один временный объект, один не временный, Foo ctors вызывается дважды (один раз для невременного, один раз для временного), а оператор =() вызывается один раз.

  3. Нет, эта линия не звонит operator=(). Когда вы инициализируете obj3 с использованием синтаксиса =, это почти так же, как если бы вы использовали скобки вместо: Foo obj3(Foo(args)); Итак, эта строка создает временный объект, а затем вызывает копию Foo ctor для инициализации obj3 с использованием этого временного объекта.

1

Ваша терминология немного запутанна.

Объекты obj, obj2obj3 не называются «временными объектами». Только экземпляр, созданный в строке 3 перед назначением obj, является временным объектом.

Кроме того, вы не создаете «копию Foo», вы создаете «экземпляр Foo» или «объект типа Foo».

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