C++ 对象创建和构造函数
Posted
技术标签:
【中文标题】C++ 对象创建和构造函数【英文标题】:C++ object creation and constructor 【发布时间】:2012-02-05 07:52:12 【问题描述】:我现在正在学习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 个临时对象和 1 个 ctor 调用。
我理解对了吗?如果是真的,编译器(例如最后一个 gcc)会在常见情况下优化这些吗?
【问题讨论】:
operator=()
通常通过引用接收它的参数,所以在调用它时没有副本。
obj3 实际上是使用复制构造函数而不是赋值运算符创建的。
【参考方案1】:
我先评论第三个:
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
引用的参数(这是它应该做的)。
关于第一个,你是对的。
【讨论】:
好的,谢谢。但无论如何,在第一种情况下,只创建了 1 个Foo
类型的对象,在第三种情况下:2 个对象?
不,根据规范,第 1 部分和第 3 部分是指定同一事物的两种方式。实现上没有区别。
@MrLister:不。1
和 3
之间存在细微差别。只需编写一个测试代码,并制作复制构造函数private
。第一个会编译,第三个不会!
噢。我敢肯定,当我学习 C++ 时,我就被教过这个。但你是对的,它不会编译。而且我找不到将它作为同义词的引用。所以,谢谢和抱歉。我会要回我的钱。【参考方案2】:
是的,Foo obj(args)
创建一个 Foo 对象并调用一次 ctor。
obj2
不被视为临时对象。但就像 1 Foo obj2
创建一个对象并调用 Foo
ctor。假设你的意思是obj2 = Foo(args)
用于下一行,这一行会创建一个临时 Foo 对象,然后调用obj2.operator=()
。因此,对于第二个示例,只有一个临时对象,一个非临时对象,Foo ctor 被调用两次(一次用于非临时对象,一次用于临时对象)并且 operator=() 被调用一次。
不,此行不调用operator=()
。当您使用=
语法初始化obj3
时,几乎就像您使用了括号一样:Foo obj3(Foo(args));
所以这一行创建了一个临时对象,然后调用 Foo 复制 ctor 使用该临时对象初始化 obj3。
【讨论】:
【参考方案3】:您的术语有点混乱。
对象obj
、obj2
obj3
不称为“临时对象”。只有在分配给 obj 之前在第 3 行中创建的实例是临时对象。
此外,您不会创建“Foo 的副本”,而是创建“Foo 的实例”或“Foo 类型的对象”。
【讨论】:
以上是关于C++ 对象创建和构造函数的主要内容,如果未能解决你的问题,请参考以下文章