C++中的构造函数与拷贝构造的优化处理

来源:互联网 发布:seo如何添加栏目 编辑:程序博客网 时间:2024/05/30 22:45

1.C++对传参和传返回值时构造的优化处理。
先简单介绍一下C++类中的默认成员函数:


(1)构造函数
成员变量为私有的,要对它们进行初始化,必须用一个公有成员函数来进行。同时这个函数应该有且仅在定义对象时自动执行一次,这时
调用的函数称为构造函数(constructor) 。
构造函数是特殊的成员函数,其特征如下:
a. 函数名与类名相同。
b. 无返回值。
c. 对象构造(对象实例化)时系统自动调用对应的构造函数。
d. 构造函数可以重载。
e. 构造函数可以在类中定义,也可以在类外定义。
f. 如果类定义中没有给出构造函数,则C++编译器自动产生一个缺省的构造函数,但只要我们定义了一个构造函数,系统就不会自动
生成缺省的构造函数。


(2)拷贝构造函数
创建对象时使用同类对象来进行初始化,这时所用的构造函数称为拷贝构造函数(Copy Constructor),拷贝构造函数是特殊的构造函
数。
特征:
a. 拷贝构造函数其实是一个构造函数的重载。
b. 拷贝构造函数的参数必须使用引用传参,使用传值方式会引发无穷递归调用。(思考为什么?)
c. 若未显示定义,系统会默认缺省的拷贝构造函数。缺省的拷贝构造函数会,依次拷贝类成员进行初始化。
赋值运算符的重载是对一个已存在的对象进行拷贝赋值。
g. 无参的构造函数和全缺省值的构造函数都认为是缺省构造函数,并且缺省的构造函数只能有一个。


(3)赋值运算符重载
拷贝构造函数是创建的对象,使用一个已有对象来初始化这个准备创建的对象。

(4)析构函数

当一个对象的生命周期结束时,C++编译系统会自动调用一个成员函数,这个特殊的成员函数即析构函数(destructor)
构造函数是特殊的成员函数,其特征如下:
a. 析构函数在类名加上字符~。
b. 析构函数无参数无返回值。
c. 一个类有且只有一个析构函数。若未显示定义,系统会自动生成缺省的析构函数。
d. 对象生命周期结束时,C++编译系统系统自动调用析构函数。
e. 注意析构函数体内并不是删除对象,而是做一些清理工作。

C++对传参和传返回值的优化处理可以用几个例子来说明:

有一个Date类,代码如下:

class Date{public :Date()           //构造{cout<<"Date()" <<endl;}Date(const Date& d){cout<<"Date(const Date& d)" <<endl;          //拷贝构造}Date& operator =(const Date& d )             //赋值运算符重载{cout<<"Date& operator=(const Date& d)"<< endl;return *this ;}~ Date()                //析构{cout<<"~Date()" <<endl;}};
有三个函数分别对应六种情况:

// 1.Date 对象做参数传值 & 传引用void fun1 (Date d) //void fun1(Date& d){}// 2.Date 对象做返回值传值 & 传引用Date fun2 () // Date& fun2(){Date d ;return d ;}// 3.Date 对象做临时返回值传值 &传引用(编译器优化问题)Date fun3 () // Date& fun3(){return Date ();}
(1)第一个函数

(2)第二个函数

(3)第三个函数



总结:

在c++中,传参和传返回值时,如果是引用类型,则不用调用拷贝构造函数,直接返回别名。

当语句为一个表达式时,编译器会选择优化,将构造函数与拷贝构造合并。

在C++中,调用几次构造函数和拷贝构造函数,就会相应的调用几次析构函数。

只有当一个对象已经存在时,d=f()才调用赋值运算符重载,如果对象不存在,则调用的是构造函数。


2.完成下面的题目。

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));