二十一、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++ 是一门以效率见长的语言(虽然近来越来越多的人“不齿”谈及效率,我深以为不然,在某一次的程序编写中不对效率锱铢必较并不意味意味着我们就不应该追求更多的更好的做法).总之吧,相比起其它语言,程序员 ...
随机推荐
- Etherscan API 中文文档-账号
本文原文链接 点击这里获取Etherscan API 中文文档(完整版) 完整内容排版更好,推荐读者前往阅读. 账号(Account) 账号及地址相关的 API,接口的参数说明请参考Etherscan ...
- es6入门5--class类的基本用法
在ES6之前,准确来说JavaScript语言并无类的概念,却有模拟类的做法.相比在类似java这类传统面向对象语言中通过类来生成实例,js则通过构造函数模拟类来生成实例. 这是因为在JS设计初期,作 ...
- 在windows IIS服务商配置asp.net core的服务器坏境,并部署
翻译自https://docs.microsoft.com/en-us/aspnet/core/publishing/iis 另一篇参考的文章 http://www.c-sharpcorner.com ...
- Python多继承C3算法
Python3 多继承的MRO算法选择.MRO(Method Resolution Order):方法解析顺序. Python3 只保留了C3算法! C3算法解析: 1.C3算法解析 C3算法:MRO ...
- csdn自动展开+去广告+净化剪切板+免登陆(如有侵权,立即删博)
对于csdn的广告大家想必......又没钱充VIP,怎么办,下面是脚本源码: 重要的事说三遍:如有侵权,立即删除!如有侵权,立即删除!如有侵权,立即删除! // ==UserScript== // ...
- TPU的相关资料
1.谷歌 TPU 的强大与局限:TPU/GPU/CPU性能功耗全面对比:http://www.sohu.com/a/134315786_473283 2.谷歌发布TPU论文,75位联合作者,GPU迎来 ...
- 072 Edit Distance 编辑距离
给出两个单词 word1 和 word2,找出将 word1 转换成 word2 所使用的最少的步骤数 (每个操作记为一步).你可以对一个单词进行以下三种操作:a) 插入一个字符b) 删除一个字符c) ...
- 2015博客升级记(五):CentOS 7.1编译安装PHP7
https://typecodes.com/web/centos7compilephp7.html
- 对于拼接进去的html原来绑定的jq事件失效
JQ拼接显示的页面中鼠标事件失效 由于是先加载html在用js层绑定的所有后来加进来的html内容就不再绑定js了 所以我们需要利用delegate绑定,但是同样道理也不能写在普通的方法层里,因为这样 ...
- SpringMVC+Thymeleaf 简单使用
一.简介 1.Thymeleaf 在有网络和无网络的环境下皆可运行,而且完全不需启动WEB应用,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果.浏览器解释 h ...