我现在正在学习ctors并且有一些问题。在这些方面:
Foo obj(args);
Foo obj2;
obj2 = Foo(args);
Foo obj3 = Foo(args);
第一部分:只初始化了一个名为(Foo)和obj
的构造函数。所以,1个对象创建。
第二部分:创建临时对象obj2
,为其调用默认ctor。接下来,我们会创建Foo
的另一个副本,并将其副本传递给operator=()
。是对的吗?所以,3个本地临时对象,2个构造函数调用。
第三部分:创建1个对象Foo
并将其副本传递给operator=()
。所以,2个temprorary对象和1个ctor调用。
我明白这一点吗?如果这是真的,编译器(例如,最后的gcc)会在常见情况下优化这些吗?
答案 0 :(得分:8)
我将先评论第三个:
Foo obj3=Foo(args);
它不使用称为复制分配的operator=
。相反,它调用copy-constructor(理论上)。这里没有任务。理论上,有两个对象创建,一个是临时的,另一个是obj3
。编译器可能会优化代码,完全省略临时对象的创建。
现在,第二个:
Foo obj2; //one object creation
obj = Foo(args); //a temporary object creation on the RHS
这里第一行创建一个对象,调用默认构造函数。然后它调用operator=
传递从表达式Foo(args)
创建的临时对象。所以有两个对象只有operator=
通过const
引用获取参数(这是它应该做的)。
关于第一个,你是对的。
答案 1 :(得分:3)
是的,Foo obj(args)
创建一个Foo对象并调用一次ctor。
obj2
不被视为临时对象。但就像1 Foo obj2
创建一个对象并调用Foo
ctor一样。假设您对下一行意味着obj2 = Foo(args)
,则此行创建一个临时Foo对象,然后调用obj2.operator=()
。所以对于第二个例子,只有一个临时对象,一个非临时对象,Foo ctors被调用两次(一次用于非临时对象,一次用于临时对象),operator =()被调用一次。
不,此行不会调用operator=()
。当您使用obj3
语法初始化=
时,它几乎就像您使用了括号一样:Foo obj3(Foo(args));
因此,此行创建一个临时对象,然后调用Foo copy ctor进行初始化obj3使用该临时对象。
答案 2 :(得分:2)
你的术语有点令人困惑。
对象obj
,obj2
obj3
不称为“临时对象”。只有在分配给obj之前在第3行中创建的实例才是临时对象。
此外,你不创建“Foo的副本”,你创建“Foo的实例”或“Foo类型的对象”。