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

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

注意

:调用构造函数的次数+调用拷贝构造的次数=析构的次数
本例中 有一个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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值