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
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:
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:
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:
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:
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