神秘的临时对象
2018-01-23 11:36
120 查看
1 有趣的问题
下面的程序输出什么?为什么?实例分析:有趣的问题
#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; }
发生了什么
程序意图:在Test()中以0作为参数调用Test(int i);
将成员变量mi的初始值设置为0。
运行结果:
成员变量mi的值为随机值。
究竟哪个地方出了问题?
思考
构造函数是一个特殊的函数:是否可以直接调用?(可以,手工调用构造函数)
是否可以在构造函数中调用构造函数?(可以,编译不会报错)
直接调用构造函数的行为是什么?
2 临时对象
直接调用构造函数的地方将产生一个临时对象。临时对象的生命周期只有一条语句的时间。
临时对象的作用域只在一条语句中。
临时对象是C++中值得警惕的灰色地带。
编程实验:解决方案
#include <stdio.h> class Test { int mi; void init(int i) { mi = i; } public: Test(int i) { init(i); } Test() { init(0); } void print() { printf("mi = %d\n", mi); } }; int main() { Test t; t.print(); return 0; }
编译器的行为
现代C++编译器在不影响最终执行结果的前提下,会尽力减少临时对象的产生!编程实验:神秘的临时对象
#include <stdio.h> class Test { int mi; public: Test(int i) { printf("Test(int i) : %d\n", i); mi = i; } Test(const Test& t) { printf("Test(const Test& t) : %d\n", t.mi); mi = t.mi; // 成员函数只有一套,成员函数能够直接访问对应类的所有的成员变量。 } Test() { printf("Test()\n"); mi = 0; } int print() da07 { printf("mi = %d\n", mi); } ~Test() { printf("~Test()\n"); } }; Test func() { return Test(20); } int main() { Test t = Test(10); // ==> Test t = 10; //1.生成临时对象。2.用临时对象初始化t对象。 //==> 调用拷贝构造函数(为了高效,编译器进行了优化,忽略了这个过程) Test tt = func(); // ==> Test tt = Test(20); ==> Test tt = 20; t.print(); tt.print(); return 0; }
小结
直接调用构造函数将产生一个临时对象。临时对象是性能的瓶颈,也是bug的来源之一。
现代C++编译器会尽力避开临时对象。
实际工程开发中需要人为避开临时对象。
相关文章推荐
- 《 C++深度剖析》学习日志十八——神秘的临时对象
- 第二十三课:神秘的临时对象----------狄泰软件学院
- 第23课 神秘的临时对象
- 第23课 - 神秘的临时对象
- 关于c++临时对象几个链接
- c++类中的临时对象
- STL源码分析--仿函数 & 模板的模板参数 & 临时对象
- c++ 临时对象的来源
- 临时对象专题
- c++ 赋值构造函数 临时变量 临时对象 之一
- C++产生的临时对象引用
- 与临时对象的斗争(下)
- 静态成员和临时对象
- javacard 临时对象 永久对象
- c++ 临时对象
- 浅析C++临时对象的产生相关问题
- java中将对象写到临时文件,并让临时文件在何时的时候自动删除
- 【M19】了解临时对象的来源
- C++中的临时对象
- [转]一个关于临时对象的BUG(下)