对象的构造顺序:
1、对于局部对象,构造顺序是根据程序执行流进行构造,从上到下。
#include <stdio.h> class Test { int mi; public: Test() { printf("Test() "); } Test(int v) { printf("Test(int v) v = %d ",v); mi = v; } int getMi(void) { return mi; } }; int main() { int i=0; Test();//输出Test() while(i<3) Test(++i);//输出 Test(int v) v = 1,2,3 /*输出 Test(int v) v = 100*/ if(i<3) Test(i); else Test(100); return 0; }
运行结果:
Test() Test(int v) v = 1 Test(int v) v = 2 Test(int v) v = 3 Test(int v) v = 100
2、对于堆对象,程序到达new语句时创建对象,使用new构造时自动调用构造函数。
#include <stdio.h> class Test { int mi; public: Test() { printf("Test() "); mi = 123; } Test(int v) { printf("Test(int v) v = %d ",v); mi = v; } Test(const Test& obj)//拷贝构造函数 { printf("Test(const Test& obj) v = %d ",obj.mi); mi = obj.mi; } int getMi(void) { return mi; } }; int main() { int i=0; Test* p = new Test();//输出Test() while(i<3) new Test(++i);//输出 Test(int v) v = 1,2,3 /*输出 Test(int v) v = mi*/ if(i == 3) new Test(*p); else new Test(100); return 0; }
运行结果:
Test() Test(int v) v = 1 Test(int v) v = 2 Test(int v) v = 3 Test(const Test& obj) v = 123
从运行结果看出,使用new关键字在堆上定义对象。构造顺序是根据new出现的顺序进行构造的。
3、对于全局对象,构造顺序是不确定的。
构析函数:
构析函数是构造函数的逆过程。自动销毁对象。格式 ~class_name()
特点:
1、不能够任何返回类型。
2、不能有任何参数。
3、在对象销毁时自动调用。
构析函数定义准则:
当类中自定义了构造函数,并且构造函数中使用了系统资源,则需要调用到构析函数。
#include <stdio.h> class Test { int mi; public: Test() { printf("Test() "); mi = 123; } Test(int v) { printf("Test(int v) v = %d ",v); mi = v; } Test(const Test& obj)//拷贝构造函数 { printf("Test(const Test& obj) v = %d ",obj.mi); mi = obj.mi; } ~Test() { printf("~Test() = %d ",mi); } int getMi(void) { return mi; } }; int main() { int i=0; Test* p = new Test();//输出Test() while(i<3) new Test(++i);//输出 Test(int v) v = 1,2,3 /*输出 Test(int v) v = 100*/ if(i == 3) new Test(*p); else new Test(100); delete p; return 0; }
打印结果:当调用 delete p;时自动调用到了 ~Test()这个构析函数
Test() Test(int v) v = 1 Test(int v) v = 2 Test(int v) v = 3 Test(const Test& obj) v = 123 ~Test() = 123
临时对象:
1、直接调用构造函数将产生一个临时对象。
2、临时对象的生命周期只有一条语句的时间。
3、临时对象的作用域只有一条语句。
4、在编程是应该尽量避免临时对象的出现。