C++暂时对象
C++真正所谓的暂时对象是不可见的——不会在你的源码中出现。仅仅要你产生一个non-heap object而没有为它命名,便诞生了一个暂时对象。此等匿名对象通常发生于两种情况:
一是当隐式类型转换(implicit type conversions)被施行起来以求函数调用可以成功。
二是当函数返回对象的时候;
其实另一种情况就是当你建立一个non-heap object对象,也就是无名对象的时候。
这里举一个常见的easy忽视的错误:
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
string s1("a"),s2("b");
const char * s = (s1+s2).c_str();
printf("%s\n",s);
}
这个程序执行的时候你可能会得到正确的结果,但其实这里的做法是不安全的,s1+s2产生的暂时对象会在表达式的结尾被析构。所以假设跟踪堆栈会发如今print语句中s的内存空间已经指向未知地址了。
这里针对3种会产生暂时对象的情况举例进行说明:
1.隐式类型转换
void uppercasify(string& str);
// changes all chars in str to upper case
char subtleBookPlug[] = "Effective C++";
uppercasify(subtleBookPlug); //error!!!
由于要使函数调用成功,必须将subtleBookPlug转换成string类型,而编译器觉得你要改变的subtleBookPlug。而类型转换后将产生一个类型为string的暂时对象,而在void uppercasify(string& str)中。被改变的将是这个暂时对象,而不是subtleBookPlug,这显然不是程序猿所期望的。所以C++明智地禁止了这样的行为
2.函数返回对象
#include <iostream>
using namespace std;
int func() {
int itgr;
return itgr;
}
int main(int argc, char *argv[]) {
int in;
in = func();
}
函数中的返回值会以值拷贝的形式复制到被调用函数栈中的一个暂时对象。这里表达式func()创建了一个暂时对象。用来存储func()函数返回的对象,暂时对象由func()返回的itgr对象拷贝构造。暂时对象赋值给in后,赋值表达式结束,暂时对象被析构。所以这里就有一个问题。
int& intref = func();
假设用一个暂时对象去初始化intref引用,一旦该表达式执行结束,暂时对象的生命周期也就结束了。引用的实体已经不复存在。
3.no heap的对象
int& intref = int(5);
int itgr = int(5);
Calculate(int(5));
上述表达式中的暂时对象用来完毕初始化引用。拷贝构造和实參等作用。
关于暂时对象生命周期的延长等问题,后面的博客再更新吧。越来越觉得C++真心麻烦…
C++暂时对象的更多相关文章
- Python-面向对象 (二 继承)
一 继承 基类定义例如以下: class people: #define attribute name = '' age = 0 #define private ...
- hibernate中持久化对象的生命周期(三态:自由态,持久态,游离态 之间的转换)
三态的基本概念: 1, 暂时状态(Transient):也叫自由态,仅仅存在于内存中,而在数据库中没有对应数据.用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫暂时对象 ...
- C++ Primer 学习笔记_62_重载操作符与转换 --调用操作符和函数对象
重载操作符与转换 --调用操作符和函数对象 引言: 能够为类类型的对象重载函数调用操作符:一般为表示操作的类重载调用操作符! struct absInt { int operator() (int v ...
- Effective C++:条款28:避免返回 handles 指向对象内部成员
(一) 有时候为了让一个对象尽量小,能够把数据放在另外一个辅助的struct中,然后再让一个类去指向它.看以下的代码: class Point { public: Point(int x, int y ...
- C++生产和使用的临时对象
所谓暂时对象就是一种无名对象. 它的出现假设不在程序猿的预期之下(比如不论什么pass by value操作都会引发copy操作,于是形成一个暂时对象),往往照成效率上的负担. 但有时候能够制造 ...
- hibernate在持久对象的生命周期(三州:自由状态,持久状态,自由状态 之间的转换)
三种状态的基本概念: 1. 临时身份(Transient):也被称为自由状态,它只存在于内存中,并且在数据库中没有相应的数据. 使用new创建的对象,久化,没有处于Session中,处于此状态的对象 ...
- 切勿创建包括auto_ptr的容器对象
当你拷贝一个auto_ptr时,它所指向的对象的全部权被移交到拷入的auto_ptr上,而它自身被置为NULL.我的理解是:拷贝一个auto_ptr意味着改变它的值.比如: auto_ptr&l ...
- Java 并发编程(二)对象的公布逸出和线程封闭
对象的公布与逸出 "公布(Publish)"一个对象是指使对象可以在当前作用域之外的代码中使用.可以通过 公有静态变量.非私有方法.构造方法内隐含引用 三种方式. 假设对象构造完毕 ...
- Java中对象与引用
初学Java 时.在非常长一段时间里,总认为基本概念非常模糊. 后来才知道.在很多Java 书中.把对象和对象的引用混为一谈. 假设分不清对象与对象引用,那实在没法非常好地理解以下的面向对象技术.把自 ...
随机推荐
- OpenWrt compiles
make -r world: build failed. Please re-run make with -j1 V=s to see what's going onmake: *** [world] ...
- lua 类实现
Class={}; Class.classList={}; --保存所有已经定义过的类 --类的类型: 类和接口, 接口也是一种类 Class.TYPE_CLASS="Class" ...
- android stagefright awesomeplayer 分析
主要调用awesomeplay.cpp的函数来实现音视频等功能,可以说是对awesomeplay.cpp的封装,进一步抽象,然后提供给上层调用,主要的调用者是MediaPlayerService.cp ...
- React-Native之ViewPagerAndroid的使用
刚接触React-Native不久,我就被深深折服了. 前几天做项目用到了ViewPager做广告页,在研究了一番官方文档之后,终于也是大体做出来了,今天就分享给大家吧. 其实,大家如果使用过Andr ...
- MVC 笔记(二)
HttpUtility.HtmlEncode来预处理用户输入,这能阻止用户向视图中用链接注入js代码或html标记 .[Required]:非空验证 .[StringLength(**)]:设置字符的 ...
- WindowsForm 打印
打印: 打印对话框:printdialog 页面设置:pagesetupdialog 这两个对话框都需要通过设置printdocument来指定打印对象 printdocument:打印对象,必须要有 ...
- 入门指引 - PHP手册笔记
曾经简单的学习过PHP,看的是<PHP和MySQL Web开发>,还有万能的搜索引擎的帮助.这次准备系统的学习一下,参考资料是PHP Manual. PHP能做什么 PHP主要用于服务端的 ...
- mysql拒绝访问(Error 1044/1045)问题的解决
遇到此问题 一般是权限问题 修改权限即可 然后用grant命令下放权限. GRANT ALL PRIVILEGES ON *.* TO root@localhost IDENTIFIED BY 'ro ...
- KNN(k-nearest neighbor的缩写)又叫最近邻算法
KNN(k-nearest neighbor的缩写)又叫最近邻算法 机器学习笔记--KNN算法1 前言 Hello ,everyone. 我是小花.大四毕业,留在学校有点事情,就在这里和大家吹吹我们的 ...
- js的体会
关于观察者模式的核心是: 回调函数, 传递函数名作为参数,或者是传递变量,然后调用其函数名. 关于闭包的核心是 闭包的函数是全局变量之下的函数, 而非闭包的函数是局部变量. <script> ...