构造拷贝构造的N中调用情况的问题

来源:互联网 发布:soulmate 知乎 编辑:程序博客网 时间:2024/06/07 19:52

简单的写一个日期类,包含四个默认成员函数

注意

:调用构造函数的次数+调用拷贝构造的次数=析构的次数
本例中 有一个Date变量和main函数的生命周期是一样的,所以会少一次析构。
如果把测试用例封装到函数中,则调用析构的次数正确。

#pragma once#include<iostream>using namespace std;class Date{public:    Date()    {        cout <<"构造函数" <<"Date()" << endl;    }    Date(const Date& x)    {        cout << "拷贝构造" << "Date(const Date& x)" << endl;    }    ~Date()    {        cout << "析构函数" << "~Date()" << endl;    }    Date& operator= (const Date& x)    {        cout << "赋值运算符重载" << "Date& operator= (const Date& x)" << endl;        return *this;    }};

测试用例

1.

void f1(Date d)//void f1(Date& d)//传引用减少拷贝构造{}
int main(){    Date d1;//会调用一次构造    f1(d1);//传值时会调用一次拷贝构造    system("pause");}

运行结果:这里写图片描述
2.

Date f2()//Date& f2()//返回引用减少一次拷贝构造{    Date ret;//会调用一次构造函数    return ret;//返回值时会产生临时变量(一次拷贝),临时变量再返回(一次拷贝),编译器优化只会调用一次拷贝构造}
int main(){    f2();    system("pause");}

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

3.

Date f3(){    Date ret;//会调用一次构造    return ret;//返回值时会产生临时变量(一次拷贝),临时变量再返回(一次拷贝),编译器优化只会调用一次拷贝构造}
int main(){    Date d1 = f3();//上式所说的优化只能是在同一表达式中    system("pause");}

运行结果:
这里写图片描述
4.

Date f4(){    return Date();    //返回值时会产生临时变量(一次拷贝),紧接着Date()会调用一次构造,编译器优化成一次构造,临时变量再返回(一次拷贝)和一次构造优化成一次构造。    //对比测试用例3,测试用例3已经构造好了在返回的,所以会合并成一次拷贝构造}
int main(){    Date d1 = f4();    system("pause");}

运行结果:
这里写图片描述
5.

void f5(Date d){}
int main(){    Date d5;//一次构造    f5(d5);//一次拷贝    system("pause");}

运行结果:
这里写图片描述
6.

void f6(Date d){}
int main(){    f6(Date());//一次构造    system("pause");}

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

总结


1.传引用会减少拷贝构造,如测试用例1和5
2.返回值时会优化(如测试用例2),返回值在一个表达式内也会优化(如测试用例3)
3.如果传值(如测试用例6)或者是返回值(如测试用例4)都是类类型,并且会调用构造函数,那么会优化为构造函数构造

经典面试题:

class AA{public:    AA()    {        cout <<"构造函数" <<"AA()" << endl;    }    AA(const AA& x)    {        cout << "拷贝构造" << "AA(const AA& x)" << endl;    }    ~AA()    {        cout << "析构函数" << "~AA()" << endl;    }    AA& operator= (const AA& x)    {        cout << "赋值运算符重载" << "AA& operator= (const AA& x)" << endl;        return *this;    }};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();    system("pause");}

test1运行结果:
这里写图片描述
test2运行结果:
这里写图片描述
test3运行结果:
这里写图片描述

阅读全文
0 0
原创粉丝点击