2012-01-08 169 views
6

我正在学习ctors并且有几个问题。在这些行:C++对象创建和构造函数

Foo obj(args); 

Foo obj2; 
obj = Foo(args); 

Foo obj3 = Foo(args); 

第一部分:只有1称为构造(美孚)和obj被初始化。所以,1个对象的创建。

第二部分:创建临时对象obj2,为其调用默认ctor。接下来我们创建Foo的另一个副本,并将其副本传递到operator=()。是对的吗?所以,3个本地临时对象,2个构造函数调用。

第三部分:创建1个对象Foo并将其副本传递到operator=()。所以,2个临时对象和1个Ctor调用。

我理解这个权利吗?如果这是真的,编译器(例如最后的gcc)在常见情况下优化这些吗?

+0

'operator =()'通常通过引用接收它的参数,所以在调用它时没有副本。 – rodrigo 2012-01-08 11:59:53

+0

obj3实际上是使用复制构造函数而不是指定操作符创建的。 – 2012-01-08 11:59:56

回答

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 2012-01-08 12:01:27

+0

不,根据规格,第1部分和第3部分是指定相同事物的两种方式。实施没有区别。 – 2012-01-08 12:11:42

+2

@MrLister:不。“1”和“3”之间有细微的差别。只需编写一个测试代码,并使复制构造函数为private。第一个会编译,第三个不会! – Nawaz 2012-01-08 12:21:45

3
  1. 是的,Foo obj(args)创建一个Foo对象并调用一次ctor。

  2. obj2不被视为临时对象。但就像1 Foo obj2创建一个对象并调用Foo ctor。假设您的下一行代表obj2 = Foo(args),则此行创建一个临时Foo对象,然后调用obj2.operator=()。因此,对于第二个示例,只有一个临时对象,一个非临时的,Foo ctors被调用两次(一次是非临时的,一次是临时的),并调用operator =()一次。

  3. 不,这条线不叫operator=()。当使用=语法初始化obj3时,它几乎和使用括号代替一样:Foo obj3(Foo(args));因此,此行创建一个临时对象,然后调用Foo copy ctor以使用该临时对象初始化obj3。

1

您的术语有点混淆。

对象obj,obj2obj3不称为“临时对象”。只有在分配给obj之前在第3行中创建的实例才是临时对象。此外,您不创建“Foo副本”,您可以创建“Foo实例”或“Foo类型对象”。