Talking about Compiler's Optimization of Constructor and Copy Construction

I. Introduction

①Let's look at a program first, passing parameters by value and passing parameters by reference

#include <iostream>
using namespace std;

class D
{
public:
	D(int a=0)//构造
		:_a(a)
	{
		cout << "D(int a=0)" << endl;
	}
	D(const D& d)//拷贝
	{
		_a = d._a;
		cout << "D(const D& d)" << endl;
	}
	~D()//析构
	{
		cout << "~D()" << endl;
	}
private:
	int _a;
 };
void  Func1(D &d)
{

}
void  Func2(D d)
{

}

int main() {
	
	D d;
	printf(".......");
	Func2(d);//传值传参
	printf("...");
	Func1(d);//传引用传参

	return 0;
}

result 

e17740ca85bb4adbb8a87c5f4f06010e.png

 It can be found that the copy construction is called by passing parameters by value, and the copy construction is not called by passing parameters by reference

② Then look at the following program, return by value and return by reference

#include <iostream>
using namespace std;

class D
{
public:
	D(int a=0)//构造
		:_a(a)
	{
		cout << "D(int a=0)" << endl;
	}
	D(const D& d)//拷贝
	{
		_a = d._a;
		cout << "D(const D& d)" << endl;
	}
	~D()//析构
	{
		cout << "~D()" << endl;
	}
private:
	int _a;
 };
D  Func1(D &d)
{
	return d;
}
 D& Func2(D& d)
{
	 return d;
}

int main() {
	
	D d;
	printf(".......");
	Func1(d);//传值返回
	printf("...");
	Func2(d);//传引用返回

	return 0;
}

result:

0aabac8efd7c4115b4c63c02cd457758.png

 It can be found that return by value will call the copy constructor, and return by reference will not call the copy constructor

Summary: When passing parameters and returning values, if it is a reference, then the copy constructor will not be called, otherwise the copy constructor needs to be called

2. Compiler optimization

① Now let's talk about the optimization of the compiler, please see the following program

#include <iostream>
using namespace std;

class D
{
public:
	D(int a=0)//构造
		:_a(a)
	{
		cout << "构造D(int a=0)" << endl;
	}
	D(const D& d)//拷贝
	{
		_a = d._a;
		cout << "拷贝D(const D& d)" << endl;
	}
	~D()//析构
	{
		cout << "析构~D()" << endl;
	}
private:
	int _a;
 };
void Func(D d)
{}

int main() {
	//D(8)为匿名对象
	Func(D(8));

	return 0;
}

Looking at the above program, and then thinking about its running order, it can be imagined that the program will first call the constructor to initialize the anonymous object, and then because the function is passed by value and parameter, it is necessary to call the copy construction to copy the value of the anonymous object to Formal parameters. However, is this really the case?

If you want to learn about anonymous objects, please go here: Knowledge about anonymous objects

Look at the result:

7d759da12b4743dbb8f2d6d53e32d10b.png

 It can be found that it only calls the constructor, but not the destructor.

②Look at the following program again

#include <iostream>
using namespace std;

class D
{
public:
	D(int a=0)//构造
		:_a(a)
	{
		cout << "构造D(int a=0)" << endl;
	}
	D(const D& d)//拷贝
	{
		_a = d._a;
		cout << "拷贝D(const D& d)" << endl;
	}
	~D()//析构
	{
		cout << "析构~D()" << endl;
	}
private:
	int _a;
 };
void Func(D d)
{}

int main() {
	//会发生隐式转换 D d = D(2) ;
	D d = 2;

	return 0;
}

According to the relevant knowledge of anonymous objects, D d = 2; this statement will first call the constructor to initialize the anonymous object, and then call the copy construction to assign the value of the anonymous object to d.

result:

e74ac971e88346f681ad445c90cf771d.png

 It can be found that the result is different from our expected

③Let's move on to the last program

#include <iostream>
using namespace std;

class D
{
public:
	D(int a=0)//构造
		:_a(a)
	{
		cout << "构造D(int a=0)" << endl;
	}
	D(const D& d)//拷贝
	{
		_a = d._a;
		cout << "拷贝D(const D& d)" << endl;
	}
	~D()//析构
	{
		cout << "析构~D()" << endl;
	}
private:
	int _a;
 };
void Func(D d)
{}

int main() {
	D d1;
	Func(d1);

	return 0;
}

result:

b1198cca873544be88cd051ec724682a.png

 It can be found that at this time, the constructor is called and the copy constructor is called. Why is it different from the above result?

reason:

In an expression, continuous construction + copy construction will be optimized by the compiler to call only one copy constructor.

ok, the knowledge about the compiler's optimization of construction and copy constructors is shared here, thanks for your support

 

Guess you like

Origin blog.csdn.net/m0_72532428/article/details/130674993