首先来介绍一下C++中的四个默认函数
(1) 构造函数
成员变量为私有的,要对它们进行初始化,必须用一个公有成员函数来进行。同时这个函数应该有且仅在定义对象时自动执行一次,这时
调用的函数称为构造函数(constructor) 。
构造函数是特殊的成员函数,其特征如下:
a. 函数名与类名相同。
b. 无返回值。
d. 构造函数可以重载。
e.构造函数可以在类中定义,也可以在类外定义。
f.如果类定义中没有给出构造函数,则C++编译器自动产生一个缺省的构造函数,但只要我们定义了一个构造函数,系统就不会自动 生成缺省的构造函数。
(2) 拷贝构造函数
创建对象时使用同类对象来进行初始化,这时所用的构造函数称为拷贝构造函数(Copy Constructor),拷贝构造函数是特殊的构造函数。
特征:
a. 拷贝构造函数其实是一个构造函数的重载。
b. 拷贝构造函数的参数必须使用引用传参,使用传值方式会引发无穷递归调用。(思考为什么?)
c. 若未显示定义,系统会默认缺省的拷贝构造函数。缺省的拷贝构造函数会,依次拷贝类成员进行初始化。
赋值运算符的重载是对一个已存在的对象进行拷贝赋值。
g. 无参的构造函数和全缺省值的构造函数都认为是缺省构造函数,并且缺省的构造函数只能有一个。
(3) 赋值运算符重载
拷贝构造函数是创建的对象,使用一个已有对象来初始化这个准备创建的对象。
(4) 析构函数
当一个对象的生命周期结束时,C++编译系统会自动调用一个成员函数,这个特殊的成员函数即析构函数(destructor)
构造函数是特殊的成员函数,其特征如下:
a. 析构函数在类名加上字符~。
b. 析构函数无参数无返回值。
c. 一个类有且只有一个析构函数。若未显示定义,系统会自动生成缺省的析构函数。
d. 对象生命周期结束时,C++编译系统系统自动调用析构函数。
e. 注意析构函数体内并不是删除对象,而是做一些清理工作。
系统在什么情况下会进行优化呢?
- 当拷贝构造存在连续的赋值情况的时候,
- 当多个临时对象连续赋值的时候
简单点来说就是,再一次拷贝构造结束后,并没有直接返回给要创建的对象而是又再次进行了拷贝构造。或者是,建立一个临时对象,来进行拷贝构造,然后又返回了一个临时对象,再用这个返回的临时对象继续拷贝构造。这时候,系统就会自动优化。
下面来看一个题来理解一下这个优化的问题。
// Test1中调用了_2__次AA的拷贝构造函数,_1__次AA的赋值运算符函数的重载。
// Test2中调用了_2__次AA的拷贝构造函数,__0_次AA的赋值运算符函数的重载。
// Test3中调用了__3_次AA的拷贝构造函数,__0_次AA的赋值运算符函数的重载。
class AA
{};
AA f (AA a)
{
return a ;
}
void Test1 ()
{
AA a1 ;
a1 = f(a1);
}
void Test2 ()
{
AA a1 ;
AA a2 = f(a1);
}
void Test3 ()
{
AA a1 ;
AA a2 = f(f(a1));
}
下面就来分析一下,为什么会是这个答案