- 一般对象的生存周期在函数内,生成时生成,调用析构函数时结束或者return之后。
- 一般临时对象的结束是在该对象生成的语句分号前调用析构函数。
- 但是引用会提升临时对象的生存周期,会将生存周期提升的与引用对象的生存周期相同。
- 指针并不能提升对象的生存周期,不能指向临时对象,因为当该条语句分号结束之后会指向别处出现非法访问。
- 全局对象的生成在可执行文件加载时,在main函数之后结束
- 局部静态生成的对象在data段,所以在调用处生成,生存于整个时期
- 如下范例代码:
#include<iostream>
using namespace std;
class Test
{
public:
Test(int a = 5, int b = 5) :ma(a), mb(b)
{
cout <<this<< "Test(int, int)" << endl;
}
~Test()
{
cout << this << "~Test()" << endl;
}
Test(const Test &src) :ma(src.ma), mb(src.mb)
{
cout<<this << "Test(const Test&)" << endl;
}
void operator=(const Test &src)
{
ma = src.ma; mb = src.mb;
cout << this << "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.t1调用构造函数;2.t5调用构造函数;3.t2调用构造函数;4.t3调用拷贝构造函数;5.为了生成新的对象而显式生成临时对象是以生成临时对象的方式来生成新的对象,相当于只调用了构造函数生成t4;6.显式生成的临时对象并非为了生成新对象,调用构造函数,然后调用复制运算符重载函数,然后临时对象析构;7.与6相同3个有函数的调用;8.与6相同有3个函数的调用;9.*p1指向一个新的对象调用一次构造函数;10.*p2有两个新对象的生成;11.p3指向一个临时对象的地址,所以在p3行代码中有一次构造一次析构的调用;12.p4延长临时对象的生存周期至main函数的}之前所以有一次构造函数调用。
析构:deletep1析构p1指向的的两个对象,delete处析构p2指向的的两个对象,然后由于先构造的后析构,p4处的临时对象析构,然后t3析构,t2析构,t4析构,t5析构,t1析构。