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++暂时对象的更多相关文章

  1. Python-面向对象 (二 继承)

    一 继承   基类定义例如以下: class people:     #define attribute     name = ''     age  = 0     #define private ...

  2. hibernate中持久化对象的生命周期(三态:自由态,持久态,游离态 之间的转换)

    三态的基本概念: 1,  暂时状态(Transient):也叫自由态,仅仅存在于内存中,而在数据库中没有对应数据.用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫暂时对象 ...

  3. C++ Primer 学习笔记_62_重载操作符与转换 --调用操作符和函数对象

    重载操作符与转换 --调用操作符和函数对象 引言: 能够为类类型的对象重载函数调用操作符:一般为表示操作的类重载调用操作符! struct absInt { int operator() (int v ...

  4. Effective C++:条款28:避免返回 handles 指向对象内部成员

    (一) 有时候为了让一个对象尽量小,能够把数据放在另外一个辅助的struct中,然后再让一个类去指向它.看以下的代码: class Point { public: Point(int x, int y ...

  5. C++生产和使用的临时对象

     所谓暂时对象就是一种无名对象. 它的出现假设不在程序猿的预期之下(比如不论什么pass by value操作都会引发copy操作,于是形成一个暂时对象),往往照成效率上的负担. 但有时候能够制造 ...

  6. hibernate在持久对象的生命周期(三州:自由状态,持久状态,自由状态 之间的转换)

    三种状态的基本概念: 1.  临时身份(Transient):也被称为自由状态,它只存在于内存中,并且在数据库中没有相应的数据. 使用new创建的对象,久化,没有处于Session中,处于此状态的对象 ...

  7. 切勿创建包括auto_ptr的容器对象

     当你拷贝一个auto_ptr时,它所指向的对象的全部权被移交到拷入的auto_ptr上,而它自身被置为NULL.我的理解是:拷贝一个auto_ptr意味着改变它的值.比如: auto_ptr&l ...

  8. Java 并发编程(二)对象的公布逸出和线程封闭

    对象的公布与逸出 "公布(Publish)"一个对象是指使对象可以在当前作用域之外的代码中使用.可以通过 公有静态变量.非私有方法.构造方法内隐含引用 三种方式. 假设对象构造完毕 ...

  9. Java中对象与引用

    初学Java 时.在非常长一段时间里,总认为基本概念非常模糊. 后来才知道.在很多Java 书中.把对象和对象的引用混为一谈. 假设分不清对象与对象引用,那实在没法非常好地理解以下的面向对象技术.把自 ...

随机推荐

  1. 产生n bit所有可能的序列

    void binary(int n) { ) printf("%s\n",A); // Assume A is a global variable else { A[n-] = ' ...

  2. uva 101 by sixleaves

    这是一道很好的模拟题,用vector<int> p[maxn],建立模型,映射为maxn个堆.主要要掌握vector模拟堆操作的简单方法.接下来得思路是自顶向下的方式,逐步完善程序.首先根 ...

  3. (转)ZOJ 3687 The Review Plan I(禁为排列)

    The Review Plan I Time Limit: 5 Seconds      Memory Limit: 65536 KB Michael takes the Discrete Mathe ...

  4. java 读取固定目录下的文件(和上篇差点儿相同)

    package gao.org; import java.io.FileNotFoundException; import java.io.IOException; import java.io.Fi ...

  5. linux/module.h: No such file or directory 内核模块编译过程

    1.缺少Linux kernel头文件 To install just the headers in Ubuntu: sudo apt-get install linux-headers-$(unam ...

  6. Sybase配置中文语言支持及字符集

    在windows平台上,Sybase ASE15.0.7安装完成后默认语言是:英语(us_english),默认字符集为:cp850.cp850是一个西欧字符集,虽然也能使用cp850字符集保存汉字, ...

  7. nginx错误日志级别

    在配置nginx.conf 的时候,有一项是指定错误日志的,默认情况下你不指定也没有关系,因为nginx很少有错误日志记录的.但有时出现问题时,是有必要记录一下错误日志的,方便我们排查问题.error ...

  8. 6个理由告诉你为什么要用NAS

    当电脑硬盘容量满了,多数使用者第一个想法就是买一块几TB的硬盘来扩充,如果是笔电的使用者,第一个想到的是买一个外接式硬盘来备份资料,这样的想法并没有错,那是当你还不知道有「NAS」这个好用的东西,才会 ...

  9. F, A, MS, QM, RF的OFFER和经历 -- Final update

    昨天收到FB的电话,我的OFFER已经批下来了,这也意味着我的JOB HUNTING结束了,下 面是我这两个月来申请结果汇总: Applications (7): Facebook, Google, ...

  10. oracle使用exp与imp在本地导入导出数据

    导出: exp user/password owner=user file=你要输出的目录以及文件名,后缀为dmpexp IOTMON/iotmon owner=QSMES file=/home/or ...