C++析构函数和构造函数执行的顺序时机

本文探讨了C++中类的构造与析构函数的执行顺序,特别是涉及内嵌对象时的情况。当一个类包含另一个类的实例时,会先执行内嵌对象的构造,然后是外部类的构造。析构时则相反,先析构外部类,再析构内嵌对象。通过示例代码解释了右值引用、返回值优化(RVO)以及构造与析构的详细过程。
摘要由CSDN通过智能技术生成

当一个类中嵌入的有另一个类时,如果没有对内嵌对象初始化,则先对内嵌的默认缺省构造(有的话也是先对内嵌的不过是调用非缺省构造),再执行外层类的构造,析构时先析构外层类,再析构内层类。
我们来看一下下面这段代码的构造函数和析构函数的顺序:

#include<iostream>
#include<string>
using namespace std;

string GetMyString()
{
    return "This is a string";
}

class zheng
{
   private:
       int a;
    public:
        zheng() { a = 0;
        cout << "Mvalue copy construct" << endl; };
        zheng(zheng& z){
            cout << "Lvalue copy construct" << endl;
        }
        zheng(zheng && z){
            cout << "Rvalue copy construct" << endl;
        }
        zheng(const int&& x):a(x){
            cout << "value copy construct" << endl;
        }
        ~zheng(){
            cout << "destruct construct" << endl;
        }
        void set(int b)
        {
            a = b;
        }
};

struct test
{
    private:
        zheng a;

    public:
        test( zheng& s)
        {
            cout << "L zheng construct" << endl;
        }
        test( zheng&& s)
        {
            cout << "R zheng construct" << endl;
        }
        ~test(){
            cout << " zheng destruct" << endl;
        }
};


zheng GetMyvalue()
{
     zheng x1;
    // cout << " construct" << endl;
     //x1.set(7);
     //zheng x2(x1);
     return x1;
}

int main(int argc, char const *argv[])
{
    // {
    //     const string &s = GetMyString();//这种左引用的语法,会先调用默认构造函数开辟内存空间,然后再将引用,引用并不会调用构造函数
    // }

    // string a = "1234";
    {
         // GetMyvalue();
          //zheng s(GetMyvalue());
          //zheng y = s;
         test s{GetMyvalue()};
        //  zheng s;
        //  zheng *p = &s;  //这边只会调用一次构造函数,说明引用并不会调用构造函数

        //  zheng &x1 = s;
    }
    return 0;
}

打印结果:
在这里插入图片描述
第一个是在执行GetMyvale()函数中执行zheng x1;调用的构造函数;

第二个是在将GetMyvale()返回的对象赋值给test s时调用的test类构造函数,因为test类中有内嵌的对象,所以要先给内嵌的对象进行默认构造;

第三个是内嵌的对象构造完毕就开始构造自己的,因为rerun返回的是临时值也即右值,所以调用的是右值引用构造函数;

第四个是函数GetMyvale()中的对象x1调用的析构函数,这里有人会有疑问了为什么不是return完就调用析构函数,而是要test的对象都构造完了才开始析构呢?
这个很好理解,因为我要将return的对象传给了test对象才能析构(也就是让test的对象都构造完了才能释放内存),不然还没传就析构删除了,test接收了个寂寞,要等参数接收完了才删除!

这里其实还有个细节,如果是之前的版本的话,在return之前x1是要析构的
但是这里会在多一个构造函数要return时要在建一个零时对象来传递x1;但是c++最新的特性有个RVO,返回值优化,就把这个建立零时对象给优化了,减少了使用内存空间,从而也就需要完成零时对象的任务,在传完参数后再析构。

第五个就是调用了test的析构函数,这里就是因为栈的内存空间是先存后去,这种格式,后构造的外层test对象要先析构删除,在析构内层的zheng对象。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值