C++关于对象的生存周期

来源:互联网 发布:windows 替换文件内容 编辑:程序博客网 时间:2024/05/17 23:36

一个最简单的对象都会有四个最基本的方法,构造函数,析构函数,拷贝和赋值。但对于一个高效的程序,它会追求更少的代码。所以我们要清楚得理解各个对象的生存周期,能少创建一个临时量就少创建一个临时量。
1.从最简单的说起,每当创建一个对象,它都是在栈上开辟的,所以和栈的操作一样,先创建的对象就最后再析构。
2.但对于全局的对象和静态的对象那就会有一点不同了,全局的对象是在程序一开始的时候都已经构造完成了,而静态的对象也有它自己的特点,那就是当程序走到这个静态对象的时候它才创建这个对象。
3.其此一点,为了提高代码的效率,我们一般要遵守几个规则:
(1)传参的时候传引用,可以不用再创建一个新的对象
(2)返回的时候返回一个临时对象
(3)构造的时候用初始化,而不是赋值。这是因为用临时量来构造同类型的新对象,临时对象会被编译器优化掉。
4.基本的规则就到这讲完了,提一下临时对象,临时对象就是在本语句后面像; , ?这些语句结束条件后就析构掉了

接下来,就用一些简单的代码来说:
class Test{public:    Test(int a=5):ma(a){cout<<"Test(int)"<<endl;}    ~Test(){cout<<"~Test()"<<endl;}    Test(const Test &src):ma(src.ma)    {cout<<"Test(const Test&)"<<endl;}    void operator=(const Test &src)    {        ma = src.ma;        cout<<"operator="<<endl;    }    int GetValue(){return ma;}private:    int ma;};Test GetTestObject(Test &t){    int value = t.GetValue();    Test tmp(value);    return tmp;}int main(){    Test t1(20);    Test t2;    t2 = GetTestObject(t1);    cout<<t2.GetValue()<<endl;    return 0;}
这个题的考点就在于对对象的生存周期的考察,来看看程序的执行顺序1.首先它创建了一个参数为20的对象2.创建了一个默认值为5的对象3.第三步程序是先进入到这个函数中,首先因为形参传的是一个引用,那么就不会生成新对象,紧接着是创建了一个tmp对象,然后是创建一个临时量,用tmp给临时量进行拷贝函数,然后析构这个tmp对象,回到主函数,把临时量赋值给了t2,然后析构这个临时量。4.最后,就是倒着析构栈里的对象,也就是t2,t1。

这里写图片描述

这个程序还算简单,我们还要说几种比较复杂的对象生存周期
class Test{public:    Test(int a=5, int b=5):ma(a), mb(b)    {cout<<"Test(int, int)"<<endl;}    ~Test()    {cout<<"~Test()"<<endl;}    Test(const Test &src):ma(src.ma), mb(src.mb)    {cout<<"Test(const Test&)"<<endl;}    void operator=(const Test &src)    {ma = src.ma; mb = src.mb; cout<<"operator="<<endl;}private:    int ma;    int mb;};Test t1(10, 10);int main(){    Test t2(20, 20);    Test t3=t2;    static Test t4 = Test(30, 30);    t2 = Test(40, 40);    t2 = (Test)(50, 50);    t2 = 60;    Test *p1 = new Test(70, 70);    Test *p2 = new Test[2];    Test *p3 = &Test(80, 80);    Test &p4 = Test(90, 90);    delete p1;    delete []p2;}Test t5(100, 100);

说到这个过程就让人头疼,过程贼多(小编到这也头大了不少)
解:
1。这里第一个可不是先构造t2哦,它是先构造了全局的对象t1参数是(10,10),t5参数是(100,100)
2。接下来才是构造t2(20,20)
3。然后是拷贝构造t3
4。t4这里要说明一下,当用临时量去构造一个对象,编译器会优化掉这个临时量,所以这里只是调用构造函数
5。接下来3个对t2的赋值方法都是一样的,先构造临时量,再赋值给t2,最后再析构掉临时量,
6。接下来注意是指针操作而不是赋值操作,p1是指向了一个构造一个参数为(70,70)的对象;p2指向了一个数组,每个数组中都创建了一个对象,所以会有2个构造函数,接下来p3指向只是个临时量所以就是构造完再析构,而p4则不同于p3的是它的前面有一个引用&,引用会增长临时量的生存周期,所以它不会立马析构掉。
7。最后阶段就是delete和析构阶段了,在栈的倒着析构,堆上随着堆析构,全局和静态在最后倒着析构。

贴的图片可能一张贴不完,后面都是一样的析构而已。

这里写图片描述

刚学习不久,可能言语或知识点还有不全或者错误,希望后来的大牛们来能指出错误,供大家一起学习使用。

原创粉丝点击