11.C++-临时对象分析
首先来参考以下代码:
#include <stdio.h> class Test { int mi; public: Test(int i) { mi = i; } Test() { Test(0); } void print() { printf("mi = %d\n", mi); } }; int main() { Test t; t.print(); return 0; }
运行打印:
mi = 2424820
从上面代码可以看到, 定义Test t时,想通过Test()构造函数去调用Test(0),从而设置成员变量mi为0
为什么输出结果截然不同?直接调用构造函数Test(0)有什么问题?
回忆之前学的:9.C++-对象的构造函数(详解)
在对象数组之手工调用构造函数那一节,我们使用构造函数来初始化数组:
Test Tarray[3]={ Test(),Test(1), Test(2)}; //初始化对象数组里的m_val值分别为0,1,2;
可以看出,一个构造函数其实是有返回值的, 返回的是一个临时对象,然后通过返回值赋值给Tarray[]数组里.
所以上面代码,实际调用了一个临时对象,并没有设置成员变量mi,所以打印出随机值
继续深入临时对象
修改上面代码,添加一些打印信息:
#include <stdio.h> class Test { int mi; public: Test(int i) { printf("Test(int i) i=%d\n",i); //添加打印 mi = i; } Test() { printf("Test()\n"); //添加打印 printf("\nTest(0) begin\n"); //添加打印 Test(0); printf("\nTest(0) end\n"); //添加打印 } ~Test(){ printf("~Test()\n"); //添加打印 }
void print() { printf("mi = %d\n", mi); } }; int main() { Test t;
t.print(); return 0; }
运行打印:
Test() Test(0) begin Test(int i) i=0 ~Test() Test(0) end mi = 10455683 ~Test()
从打印结果可以看到,在运行Test()时,调用了:
Test(0) begin Test(int i) i=0 ~Test() Test(0) end
从上面看出:
Test(0)生成的临时对象,在运行下一条语句printf("\nTest(0) end\n");时,便调用~Test()析构函数注销了.
除此这外,当函数的参数是某个对象,而不是引用对象,也会出现临时对象的产生.
比如:
void func(Test t); //不是Test& t
也就是说:
- 直接调用构造函数将产生一个临时对象
- 临时对象的生命周期只有一条语句的时间
- 临时对象的作用域只在一条语句中
总结
在C++中,我们应该尽量减少临时对象的产生,因为从程序效率角度上看,创建临时对象和消除临时对象也需要耗费时间的
人间有真情,人间有真爱。