构造函数和拷贝构造的N种调⽤情况

来源:互联网 发布:java bufferedreader 编辑:程序博客网 时间:2024/06/05 13:26

1:C++对传参和传返回值时构造的优化处理
传参数时,传引用比传值减少一次拷贝构造; 传返回值时,编译器会进行优化,返回值在一个表达式内也会进行优化。
一般而言,调用构造和拷贝构造的次数 = 调用析构函数的次数。

2:讨论传值和传返回值得各种情况
先写一个Date类,以它的调用情况为例:

#include<iostream>using namespace std;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)//传引用{}int main(){    Date d1; //构造一次    fun1(d1); //传值时,会调用一次拷贝构造,传引用减少拷贝构造    return 0;

运行结果:传值:

这里写图片描述
传引用:
这里写图片描述

情况2:

//Date对象做返回值//Date fun2 () //传值//{//  Date d ;//会调用一次构造//  return d ;//返回值时会产生临时变量(一次拷贝),临时变量再返回(一次拷贝),编译器优化只会调用一次拷贝构造//} Date& fun2()  //传引用{    Date d;//只调一次构造返回引用,不会产生临时变量    return d;//返回引用,不会产生临时变量}int main(){    fun2();    return 0;}

运行结果:
传值:
这里写图片描述
传引用:
这里写图片描述

情况3:
将情况2的主函数改为:

 int main() {     Date d2 = fun2(); //1.一个表达式会进行优化     //Date d2;        //2.     //d2 = fun2;     return 0; }

1.的运行结果:
传值:
这里写图片描述
传引用:
这里写图片描述
2.的运行结果:
传值:
这里写图片描述
传引用:
这里写图片描述
这说明,当是一个表达式时,会进行优化,Date d2 = fun2()。

情况4:
运行结果:

//Date对象做临时返回值:传值&传引用(编译器优化问题)//Date fun3() //{//  return Date();//返回值时会产生临时变量(一次拷贝),Date()会调用一次构造,编译器会将其优化成一次构造,临时变量返回(一次构造)和优化的一次构造总共优化成一次构造。//}Date& fun3(){    return Date();//返回引用,则Date()会调用一次构造,没有临时变量的开销}int main(){    fun3();    return 0;}

传值:
这里写图片描述
传引用:
这里写图片描述

和情况2的区别:对象做返回值,在返回的时候是已经构造好了的;对象做临时返回值,在返回的时候还没有构造好,得先拷贝到临时变量,在进行构造。

3.面试题:
完成下面的题目。
Test1中调用了 2 次AA的拷贝构造函数,1次AA的赋值运算符函数的重载。
Test2中调用了2次AA的拷贝构造函数,0次AA的赋值运算符函数的重载。
Test3中调用了3次AA的拷贝构造函数,0次AA的赋值运算符函数的重载。

class AA{public:    AA()    {        cout<<"AA"<<endl;    }    AA(const AA& a)    {        cout<<"AA(const AA& a)"<<endl;    }    AA& operator=(const AA& a)    {        cout<<"AA& operator=(const AA& a)"<<endl;        return *this;    }    ~AA()    {        cout<<"~AA()"<<endl;    }};AA f(AA a){    return a ;}void Test1(){    AA a1 ;//一次构造    a1 = f(a1); //f(a1)传值会调用一次拷贝构造       //返回值时会产生临时变量(一次拷贝),临时变量再返回(一次赋值运算符的重载)}void Test2(){    AA a1 ;//一次构造    AA a2 = f(a1);//f(a1)传值会调用一次拷贝构造,       //返回值时会产生临时变量(一次拷贝),临时变量再返回(一次拷贝),编译器优化只会调用一次拷贝构造}void Test3(){    AA a1 ;    AA a2 = f(f(a1)); //f(a1)传值会调用一次拷贝构造        //f(a1)返回值时会产生临时变量(一次拷贝),临时变量再返回(一次拷贝),编译器优化只会调用一次拷贝构造       //f(f(a1))返回值时会产生临时变量(一次拷贝),临时变量再返回(一次拷贝),编译器优化只会调用一次拷贝构造}int main(){    //Test1();    //Test2();    Test3();    return 0;}

分析:
这里写图片描述

这里写图片描述

这里写图片描述

Test1运行结果:
这里写图片描述
Test2运行结果:
这里写图片描述
Test3运行结果:
这里写图片描述

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 冬天卖什么利润大不压货 为什么医院不卖伊曲康唑 二手房卖不掉急死人 中国为什么不让卖爆炸盐 卖不卖 3d硬金为什么不按克卖 迈之灵为什么不让卖 宝塔糖为什么不让卖 为什么黄道益不能在大陆卖 40年产权公寓卖不掉 为什么处方药不随便卖 王氏保赤丸为啥不让卖 百蕊颗粒药店为什么不让卖 14楼为什么便宜也不好卖 为什么很多药店不卖百蕊颗粒 安康鱼肝为什么不让卖 eve药中国为什么不让卖 21型二踢脚为什么不能卖 凯美瑞混动为什么卖不动 顶层房子为什么不好卖 南宁2019很多房子卖不出去 十月馨药店为什么不明卖 三不问 养龟为什么不能养双 家里为什么不能养双猫 眼科医生不建议割双眼皮 新手为什么不要开双离合 千万不要买雷凌双擎 世上安得双法不负如来不负卿 肿泡眼大夫不建议割双眼皮 双胎为什么医生不建议做四维 双闪灯一直闪关不掉怎么解决 到付邮费是不是双倍 做完双眼皮不能吃什么 甲状腺双叶回声不均匀 不可抗力3完整免费观看双结局 双钱轮胎质量好不好 双相情感障碍六亲不认 为什么双氧水不利于伤口愈合 双氧水洗耳朵会不会烧坏耳膜 双桶洗衣机脱水桶不转