C++ 对象创建和构造函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8777240/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:05:22  来源:igfitidea点击:

C++ object creation and constructor

c++objectconstructor

提问by Max Frai

I'm learning ctors now and have a few question. At these lines:

我现在正在学习 ctors 并且有一些问题。在这些行:

Foo obj(args);

Foo obj2;
obj2 = Foo(args);

Foo obj3 = Foo(args);

First part: only 1 constructor called (Foo) and objis initialized. So, 1 object creation.

第一部分:只有 1 个构造函数称为 (Foo) 并obj已初始化。因此,创建 1 个对象。

Second part: creating of temporary object obj2, calling default ctor for it. Next lines we create another copy of Fooand pass it's copy into operator=(). Is that right? So, 3 local temporary objects, 2 constructor callings.

第二部分:创建临时对象obj2,为其调用默认构造函数。接下来Foo的几行我们创建另一个副本并将它的副本传递到operator=(). 那正确吗?因此,3 个本地临时对象,2 个构造函数调用。

Third part: create 1 object Fooand pass it's copy into operator=(). So, 2 temprorary objects and 1 ctor calling.

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

Do I understand this right? And if it's true, will compiler (last gcc, for example) optimize these in common cases?

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

回答by Nawaz

I will comment on the third one first:

我先评论第三个:

Foo obj3=Foo(args);

It doesn't use operator=which is called copy-assignment. Instead it invokes copy-constructor (theoretically). There is no assignment here. So theoretically, there is two objects creation, one is temporary and other is obj3. The compiler might optimize the code, eliding the temporary object creation completely.

它不使用operator=称为复制分配的方法。相反,它调用复制构造函数(理论上)。这里没有任务。所以理论上,有两个对象创建,一个是临时的,另一个是obj3. 编译器可能会优化代码,完全消除临时对象的创建。

Now, the second one:

现在,第二个:

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

Here the first line creates an object, calling the default constructor. Then it calls operator=passing the temporary object created out of the expression Foo(args). So there is two objects only the operator=takes the argument by constreference (which is what it should do).

这里第一行创建一个对象,调用默认构造函数。然后它调用operator=传递从表达式创建的临时对象Foo(args)。所以只有两个对象operator=通过const引用获取参数(这是它应该做的)。

And regarding the first one, you're right.

关于第一个,你是对的。

回答by bames53

  1. Yes, Foo obj(args)creates one Foo object and calls the ctor once.

  2. obj2is not considered a temporary object. But just like 1 Foo obj2creates one object and calls the Fooctor. Assuming that you meant obj2 = Foo(args)for the next line, this line creates one temporary Foo object and then calls obj2.operator=(). So for this second example there is only a single temporary object, a single non-temporary, Foo ctors are called twice (once for the non-temporary, once for the temporary) and the operator=() is called once.

  3. No, this line does not call operator=(). When you initialize obj3using the =syntax it is almost exactly as if you had used parentheses instead: Foo obj3(Foo(args));So this line creates a temporary object, and then calls the Foo copy ctor to initialize obj3 using that temporary object.

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

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

  3. 不,这条线路不会调用operator=()。当您obj3使用=语法进行初始化时,它几乎与您使用括号完全一样:Foo obj3(Foo(args));因此,这一行创建了一个临时对象,然后调用 Foo 复制构造函数来使用该临时对象初始化 obj3。

回答by Mr Lister

Your terminology is a bit confusing.

你的术语有点混乱。

The objects obj, obj2obj3are not called "temporary objects". Only the instance that is created in line 3 before being assign to obj is a temporary object.

这些对象objobj2obj3不叫“临时对象”。只有在分配给 obj 之前在第 3 行中创建的实例才是临时对象。

Also, you don't create "a copy of Foo", you create either "an instance of Foo" or "an object of type Foo".

此外,您不会创建“Foo 的副本”,而是创建“Foo 的实例”或“Foo 类型的对象”。