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. [Medusa-dev] psp_handler - embed python in HTML like ASP

    [Medusa-dev] psp_handler - embed python in HTML like ASP [Medusa-dev] psp_handler - embed python in ...

  2. IOS使用C#预处理命令,多种SDK共存

    当我们使用Unity接 91,XY助手等等SDK时候. 我们需要使用[DllImport("__Internal")] 来声明一个C++的方法调用. 不同的SDK总会有不同的方法. ...

  3. c# 图片简单模糊 非高斯模糊

    /// <summary>        /// 图像模糊化        /// </summary>        /// <param name="bit ...

  4. Android应用程序窗口(Activity)实现框架简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8170307 前面我们学习了SurfaceFli ...

  5. php错误日志级别

    ; E_ALL             所有错误和警告(除E_STRICT外) ; E_ERROR           致命的错误.脚本的执行被暂停. ; E_RECOVERABLE_ERROR   ...

  6. WindowsForm 流

    流 包括输入流代码 输出流代码 流: 输入流: string filename = openFileDialog1.FileName; //通过读入流进行文件读取 StreamReader sr = ...

  7. 写sql语句注意事项

    做管理系统的,无论是bs结构的还是cs结构的,都不可避免的涉及到数据库表结构的设计,sql语句的编写等.因此在开发系统的时候,表结构设计是否合理,sql语句是否标准,写出的sql性能是否优化往往会成为 ...

  8. Servlet 学习总结-2

    #重定向与转发的区别 开发Web应用中会遇到从一个页面跳转到另一个页面的问题,在JSP中有两种跳转方式: 1.重定向 2.转发(转向) 重定向:首先服务器受到浏览器客户端请求之后,服务器发送新的链接到 ...

  9. Hadoop配置文件-mapred-site.xml

    name value Description hadoop.job.history.location   job历史文件保存路径,无可配置参数,也不用写在配置文件里,默认在logs的history文件 ...

  10. 深入研究B树索引(一)

    摘要:本文对B树索引的结构.内部管理等方面做了一个全面的介绍.同时深入探讨了一些与B树索引有关的广为流传的说法,比如删除记录对索引的影响,定期重建索引能解决许多性能问题等. 1.B树索引的相关概念 索 ...