类构造函数在向类成员函数发送不同变量时被调用。

huangapple go评论59阅读模式
英文:

Class constructor called upon sending different variables to a class member function

问题

我正在学习C++中的面向对象编程(OOP)考试,并尝试理解关于构造函数的一些内容。

在下面的代码中:

类 A:

#pragma once
#include <iostream>
using namespace std;

class A
{
public:
	A() { cout << "1"; }
	A(const A& a) { cout << "2"; }
	~A(){ cout << "3"; }

	A anyFunc(A& a1, A* a2, A a3) {
		cout << "4";
		return *a2;
	}
};

主函数:

#include "A.h"

int main() {	
	A a;
	a.anyFunc(a, &a, a);
}

这段代码输出 1242333

我理解第一个 1....,因为我们用默认构造函数创建了类型为 A 的对象 a

后来,我们将首先创建的对象分别以引用、指针和值的方式传递给了类 A 的成员函数。

我不理解编译器在此之后的操作。为什么它会使用复制构造函数并打印 2,然后打印 4,然后再次调用复制构造函数并打印 2?基本上,它创建了 a2a3。我理解最后打印的 ....333,因为如果我们创建了局部静态对象 a1a2a3,那么当这些变量最终“死亡”时,编译器会调用析构函数。

我正在努力理解C++中构造函数的工作原理。

英文:

I'm studying for an OOP test in C++, and I'm trying to understand something about the idea of constructors.

In the code below:

Class A:

#pragma once
#include &lt;iostream&gt;
using namespace std;

class A
{
public:
	A() { cout &lt;&lt; &quot;1&quot;; }
	A(const A&amp; a) { cout &lt;&lt; &quot;2&quot;; }
	~A(){ cout &lt;&lt; &quot;3&quot;; }

	A anyFunc(A&amp; a1, A* a2, A a3) {
		cout &lt;&lt; &quot;4&quot;;
		return *a2;
	}
};

Main:

#include&quot;A.h&quot;

void main() {	
	A a;
	a.anyFunc(a, &amp;a, a);
}

This code prints &quot;1242333&quot;.

I understand the first &quot;1....&quot; because we create an object a of type A with the default constructor.

Later on, we send to the member function of class A the object we created first by reference, then as a pointer, and last by value.

I don't understand what the compiler does after that. Why would it go and use the copy constructor and print &quot;2&quot;, then print &quot;4&quot;, and then again go to the copy constructor to print &quot;2&quot;? Basically, creating a2 and a3. I understand the last &quot;....333&quot; that are printed, since if we created the local static objects a1,a2,a3 then the compiler calls the destructor when those variables "die" in the end.

Trying to understand how constructors work in C++.

答案1

得分: 3

根据C++标准,没有参数的main函数应该声明为:

int main()

至于你的问题,对于这个语句:

A a;

会调用默认构造函数:

"1     "

然后在这个调用中:

a.anyFunc(a, &a, a);

为了创建与第三个参数a3相对应的对象,使用了复制构造函数:

"12    "

函数接管控制权:

"124   "

函数使用表达式*a返回类型为A的对象:

A anyFunc(A& a1, A* a2, A a3) {
    cout << "4";
    return *a2;
}

因此,再次调用复制构造函数来创建返回的对象:

"1242   "

然后对应于参数a3的对象调用析构函数:

"12423  "

接着销毁临时返回的对象:

"124233 "

最后销毁在main中定义的对象:

A a;

结果是:

"1242333"

也就是说,创建了三个对象。第一个是在main中创建的,第二个与参数a3相关,最后是返回的临时对象。对于这些对象,都调用了析构函数。

需要注意的是,如果你像这样调用函数:

a.anyFunc(a, &a, A());

那么输出将是:

1142333

这意味着第二个数字2将被省略,因为进行了复制省略。

英文:

For starters according to the C++ Standard the function main without parameters shall be declared like

int main()

As for your question then in this statement

A a;

there is called the default constructor

&quot;1     &quot;

then in this call

a.anyFunc(a, &amp;a, a);

for the third argument to create the object that corresponds to the third parameter a3 there is used the copy constructor

&quot;12    &quot;.

The function gets the control

&quot;124   &quot;.

The function returns an object of the type A using the expression *a

A anyFunc(A&amp; a1, A* a2, A a3) {
    cout &lt;&lt; &quot;4&quot;;
    return *a2;
}

So again the copy constructor is called to create the returned object

&quot;1242   &quot;.

Then the destructor is called for the object that corresponds to the parameter a3

&quot;12423  &quot;.

Then destroyed the temporary returned object

&quot;124233 &quot;.

And at last there is destroyed the object defined in main in this declaration

A a;

As a result you have

&quot;1242333&quot;.

That is there were created three objects. The first one - in main. The second one that corresponds to the parameter a3. And at last the returned temporary object. For each of these objects there was called the destructor.

Pay attention to that if you would call the function like

a.anyFunc( a, &amp;a, A() );

then the ouput would be

1142333

That is instead of the second digit 2 there will be the digit 1 due to the copy elision.

答案2

得分: 2

1 当在 main() 中的变量 a 默认构造(对象 #1)时打印。

2anyFunc()a3 参数从 a 复制构造(对象 #2)时打印。由于 a3 是通过值传递的,它是给定的任何 A 对象的副本a1a2 参数不创建新对象,它们只是引用现有对象(在这种情况下,引用 main() 中的同一对象 - a)。

4anyFunc() 开始运行时打印。这里不创建新的 A 对象。

2 当从 *a2 复制构造 anyFunc() 的返回值(对象 #3)时再次打印。由于 anyFunc() 通过值返回一个 A 对象,它返回正在被 returnA 对象的临时副本anyFunc() 的调用者决定如何处理返回的副本 - 将其保存到本地变量中,传递给另一个函数,或者只是忽略它(就像你的示例正在做的)。

3anyFunc() 退出时打印 anyFunc()a3 参数被销毁时。

3 当由 anyFunc() 返回的临时 A 对象被销毁时打印。

3main() 退出时打印 main() 中的 a 变量被销毁时。

英文:

1 is printed when the variable a in main() is default-constructed (object #1).

2 is printed when the a3 parameter of anyFunc() is copy-constructed (object #2) from a. Since a3 is passed in by value, it is a copy of whichever A object is given to it. The a1 and a2 parameters do not create new objects, they simply refer to existing objects (in this case, to the same object - a in main()).

4 is printed when anyFunc() begins running. No new A object is created here.

2 is printed again when the return value of anyFunc() is copy-constructed (object #3) from *a2. Since anyFunc() returns an A object by value, it returns a temporary copy of whichever A object is being return'ed. The caller of anyFunc() decides what it wants to do with that returned copy - save it to a local variable, pass it to another function, or just ignore it (as your example is doing).

3 is printed when the a3 parameter of anyFunc() is destructed when anyFunc() exits.

3 is printed when the temporary A object returned by anyFunc() is destructed.

3 is printed when the a variable in main() is destructed when main() exits.

huangapple
  • 本文由 发表于 2023年2月9日 01:00:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75389196.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定