二十一、C++中的临时对象
思考:
构造函数是一个特殊的函数
- 是否可以直接调用?
- 是否可以在构造函数中调用构造函数?
- 直接调用构造函数的行为是什么?
答:
直接调用构造函数将产生一个临时对象
临时对象的生命周期只有一条语句的时间
临时对象的作用域只在一条语句中
临时对象是C++中值得警惕的灰色地带
#include <stdio.h>
class Test {
int mi;
public:
Test(int i)
{
mi = i;
}
Test()
{
Test(0);
// 调用Test(int i),得到了一个临时对象,生命周期只有这句话,过了之后临时对象就被析构,临时对象没有名字,作用域也只有这句话,过了之后,不能再被访问。这里的临时对象几乎就没有作用。这个0根本就没有设置到mi上
}
// 等价于
Test(){
};
void print() {
printf("mi = %d\n", mi);
}
};
int main()
{
Test t;
t.print();
return 0;
}
// 解决办法
// 提供一个私有的init函数,做初始设置
class Test {
int mi;
void init(int i)
{
mi = i;
}
public:
Test(int i) {
printf("Test(int i)\n");
init(i);
}
Test(){
printf("Test()\n");
init(0); // 调用的普通私有函数,不会产生临时对象
};
void print() {
printf("mi = %d\n", mi);
}
~Test()
{
printf("~Test()\n");
}
};
int main()
{
printf("main begin\n");
Test(); // 直接调用构造函数,会产生一个临时对象
Test(10); // 产生临时对象
printf("main end\n")
return 0;
}
/*结果
main begin
Test()
~Test()
Test(int i)
~Test()
*/
int main()
{
printf("main begin\n");
Test().print(); // Test()结果是一个临时对象,是一个合法的对象,然后操作它的成员函数
Test(10); // 产生临时对象
printf("main end\n")
return 0;
}
/*结果
main begin
Test()
mi = 0 // 临时对象的打印
~Test()
Test(int i)
mi = 10 // 临时对象的打印
~Test()
*/
编译器的行为:现代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()
{
printf("mi = %d\n", mi);
}
~Test()
{
printf("~Test()\n");
}
};
Test func()
{
return Test(20); // 应该是返回一个临时对象
}
int main()
{
Test t(10);
Test t = Test(10); // 1、生成一个临时对象;2、用临时对象初始化t
// ==> 调用拷贝构造函数
// 但是结果并没有打印拷贝构造函数,说明编译器没有生成临时变量
// 原因是现代编译器都会尽量减少临时变量的产生,
// 编译器将这句话等价成了 Test t(10)
// 临时变量的产生会带来性能上的问题
t.print();
Test tt = func();
tt.print(); // 会打印出20
/*
理论上应该是要调用拷贝构造函数,但是没有
编译器将这句话等价成了 ==> Test tt = Test(20) ==> Test tt = 20;
*/
return 0;
}
小结
直接调用构造函数将产生一个临时对象
临时对象是性能的瓶颈,也是BUG的来源之一
现代C++编译器会尽力避开临时对象
实际工程开发中需要认为地避开临时对象
二十一、C++中的临时对象的更多相关文章
- C++中的临时对象
1,临时对象神秘在于不知不觉就请入程序当中,并且给程序带来了一定的问题: 2,下面的程序输出什么?为什么? #include <stdio.h> class Test { int mi; ...
- 认识C++中的临时对象temporary object 分类: C/C++ 2015-05-11 23:20 137人阅读 评论(0) 收藏
C++中临时对象又称无名对象.临时对象主要出现在如下场景. 1.建立一个没有命名的非堆(non-heap)对象,也就是无名对象时,会产生临时对象. Integer inte= Integer(5); ...
- (二十一)WebGIS中鹰眼的实现思路
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 鹰眼功能是WebGIS中的一种常见功能,利用一些开源的框架实现 ...
- AngularJS进阶(二十一)Angularjs中scope与rootscope区别及联系
Angularjs中scope与rootscope区别及联系 scope是html和单个controller之间的桥梁,数据绑定就靠他了.rootscope是各个controller中scope的桥梁 ...
- 二十一、JavaScript之访问对象属性
一.代码如下 二.执行效果如下 <!DOCTYPE html> <html> <meta http-equiv="Content-Type" cont ...
- 读书笔记_Effective_C++_条款二十一:当必须返回对象时,别妄想返回其reference
在栈空间的临时成员变量在函数生命期结束后无法传出 friend A& operator*(const A& a, const A& b) { A temp; temp.data ...
- 从汇编看c++中临时对象的析构时机
http://www.cnblogs.com/chaoguo1234/archive/2013/05/12/3074425.html c++中,临时对象一旦不需要,就会调用析构函数,释放其占有的资源: ...
- 【编程篇】C++11系列之——临时对象分析
/*C++中返回一个对象时的实现及传说中的右值——临时对象*/ 如下代码: /**********************************************/ class CStuden ...
- 与临时对象的斗争(上)ZZ
C++ 是一门以效率见长的语言(虽然近来越来越多的人“不齿”谈及效率,我深以为不然,在某一次的程序编写中不对效率锱铢必较并不意味意味着我们就不应该追求更多的更好的做法).总之吧,相比起其它语言,程序员 ...
随机推荐
- pgpool-ii 安装手册 基于Centos7.3
http://www.bkjia.com/jQuery/1173582.html地址被占用pgpool启动失败 Nov 15 02:33:56 node3 pgpool: 2016-11-15 02: ...
- CODING 告诉你硅谷的研发项目管理之道系列(6)
写在前面 优秀的研发管理者是怎么工作的,如何更加高效地管理研发团队?这些一直是 CODING关注的重要话题,我们不断地打磨 CODING 研发系统来让开发更简单.近期我们精心挑选了几篇硅谷科技公司研发 ...
- Vue实例生命周期+vueRoter
Vue实例生命周期 vue生命周期之beforeCreate 实例创建之前除标签外,所有的vue需要的数据,事件都不存在 vue生命周期之created 实例创建之后,data和事件已经被解析到,el ...
- 2019湘潭校赛 E(答案区间维护)
题目传送 思路是始终维护西瓜数量的区间,即L代表目前可以达到的最少的,R是最多的,然后判断一下. #include <bits/stdc++.h> using namespace std; ...
- AWR实战分析之----direct path read temp
http://blog.sina.com.cn/s/blog_61cd89f60102eej1.html 1.direct path read temp select TOTAL_BLOCKS,USE ...
- 042 Trapping Rain Water 接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算下雨之后能接多少雨水.例如,输入 [0,1,0,2,1,0,1,3,2,1,2,1],返回 6. 详见:https://leetcode.c ...
- 使用centos7的wall防火墙可能存在失效问题
centos7有自己新的防火墙,但是仍然带有centos6.5的iptable防火墙,当新防火墙不稳定,失效时,可以采用老防火墙 以上都是在vm虚拟机上发现的问题 参考文章 https://www.c ...
- Model中的验证规则
一.能够使用Model的Attribute进行服务端数据验证 本文目录 一.概述 二.MVC提供的常用上下文 三.自定义正则表达式验证 一.概述 为了确保数据的安全性,由Client发送到服务端的每一 ...
- WebApi访问方式配置
之前公司使用webapi开发项目,只知道怎么用对于怎么配置一直不了解,最近这段时间没什么事然后自己建一个webapi项目,只知道怎么用对于怎么配置一直不了解,最近这段时间没什么事然后自己建一个weba ...
- nodejs 实践:express 最佳实践(三) express 解析
nodejs 实践:express 最佳实践(三) express 解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs 的基础不稳固, ...