下面这段代码会输出什么?
- const char* p = string("hello temprary string").c_str();
- cout << p;
下面这段代码运行之后会怎样?
- #include <vector>
- class Foo
- {
- public:
- Foo()
- {
- _p = new char[32];
- }
- ~Foo()
- {
- delete _p;
- }
- private:
- char* _p;
- };
- int main()
- {
- std::vector<Foo> cont;
- cont.push_back(Foo());
- return 0;
- }
第一个会输出奇怪的字符串,第二个会崩溃。
Why?这是临时对象提前销毁造成的。
临时对象会在什么情况下被创建,msdn上介绍有以下几种情况:
To initialize a const reference with an initializer of a type different from that of the underlying type of the reference being initialized.
-
To store the return value of a function that returns a user-defined type. These temporaries are created only if your program does not copy the return value to an object. For example:
UDT Func1(); // Declare a function that returns a user-defined
// type. ... Func1(); // Call Func1, but discard return value.
// A temporary object is created to store the return
// value.Because the return value is not copied to another object, a temporary object is created. A more common case where temporaries are created is during the evaluation of an expression where overloaded operator functions must be called. These overloaded operator functions return a user-defined type that often is not copied to another object.
Consider the expression ComplexResult = Complex1 + Complex2 + Complex3. The expression Complex1 + Complex2 is evaluated, and the result is stored in a temporary object. Next, the expression temporary + Complex3 is evaluated, and the result is copied to ComplexResult(assuming the assignment operator is not overloaded).
To store the result of a cast to a user-defined type. When an object of a given type is explicitly converted to a user-defined type, that new object is constructed as a temporary object.
临时对象何时被销毁呢,还是看msdn的介绍:
Temporary objects have a lifetime that is defined by their point of creation and the point at which they are destroyed. Any expression that creates more than one temporary object eventually destroys them in the reverse order in which they were created. The points at which destruction occurs are shown in the following table.
Reason Temporary Created |
Destruction Point |
---|---|
Result of expression evaluation |
All temporaries created as a result of expression evaluation are destroyed at the end of the expression statement (that is, at the semicolon), or at the end of the controlling expressions for for, if, while, do, and switch statements. |
Initializingconstreferences |
If an initializer is not an l-value of the same type as the reference being initialized, a temporary of the underlying object type is created and initialized with the initialization expression. This temporary object is destroyed immediately after the reference object to which it is bound is destroyed. |
注意第一条:由于表达式的计算产生的临时对象会在表达式计算完成(遇到;号)之后被销毁。
所以:
第一个问题中,p在第一行代码之后指向了一被销毁的内存。
第二个问题中,Foo在push_back的那行代码之后被销毁,_p被delete。而vector析构的时候会析构每个元素,_p又被delete,崩溃!
编译器默认的operator=只是赋值每一个字段。要解决第二个问题,可以在operator=中对_p申请另外的内存再拷贝。
关于临时对象的析构造成的问题还可以举出很多例子。掌握了它析构的时机才能很好的避免类似错误。
http://blog.csdn.net/passion_wu128/article/details/38959465
C++临时对象销毁时间的更多相关文章
-
c# -- 对象销毁和垃圾回收
有些对象需要显示地销毁代码来释放资源,比如打开的文件资源,锁,操作系统句柄和非托管对象.在.NET中,这就是所谓的对象销毁,它通过IDisposal接口来实现.不再使用的对象所占用的内存管理,必须在某 ...
-
Perl面向对象(3):解构——对象销毁
本系列: Perl面向对象(1):从代码复用开始 Perl面向对象(2):对象 Perl面向对象(3):解构--对象销毁 第3篇依赖于第2篇,第2篇依赖于1篇. perl中使用引用计数的方式管理内存, ...
-
C++ 对象构造顺序、构析函数、临时对象。
对象的构造顺序: 1.对于局部对象,构造顺序是根据程序执行流进行构造,从上到下. #include <stdio.h> class Test { int mi; public: Test( ...
-
C++中的临时对象
1,临时对象神秘在于不知不觉就请入程序当中,并且给程序带来了一定的问题: 2,下面的程序输出什么?为什么? #include <stdio.h> class Test { int mi; ...
-
【编程篇】C++11系列之——临时对象分析
/*C++中返回一个对象时的实现及传说中的右值——临时对象*/ 如下代码: /**********************************************/ class CStuden ...
-
SQL Server 内置函数、临时对象、流程控制
SQL Server 内置函数 日期时间函数 --返回当前系统日期时间 select getdate() as [datetime],sysdatetime() as [datetime2] getd ...
-
C++ 临时对象
1.什么是临时对象? swap方法中,常常定义一个temp对象,这个temp对象不是临时对象,而是局部对象.这里所说的临时对象是不可见的,在原代码中是看不到的. 2.为什么会产生临时对象? a.客户期 ...
-
【M19】了解临时对象的来源
1.首先,确认什么是临时对象.在swap方法中,建立一个对象temp,程序员往往把temp称为临时对象.实际上,temp是个局部对象.C++中所谓的临时对象是不可见的,产生一个non-heap对象,并 ...
-
[转] C++中临时对象及返回值优化
http://www.cnblogs.com/xkfz007/articles/2506022.html 什么是临时对象? C++真正的临时对象是不可见的匿名对象,不会出现在你的源码中,但是程序在运行 ...
随机推荐
-
Schwarz积分公式
设$f\in H(B(0,R))\cap C(\overline{B(0,R)})$,且$f=u+iv$,则$f$可用其实部表示为 $$f(z)=\frac{1}{2\pi}\int_{0}^{2\p ...
-
IBatis.Net使用总结(二)-- IBatis返回DataTable/DataSet(网上例子的集合)
IBatis返回DataTable,DataSet ibatis.net QueryForDataTable 完整的为ibatis.net 引入datatable支持要改动很多地方,所以描述的是最小化 ...
-
10317 Fans of Footbal Teams(并查集)
10317 Fans of Footbal Teams 时间限制:1000MS 内存限制:65535K提交次数:0 通过次数:0 题型: 编程题 语言: G++;GCC Description ...
-
spring-AOP-ProxyFactoryBean代理的实例
1.一个代理模式的实例 通过 Proxy类进行代理 wait.java //定义一个接口 public interface wait { void say(); } //目标对象实现接口并重写方法 p ...
-
【php】DIRECTORY_SEPARATOR的作用
DIRECTORY_SEPARATOR是php的内部常量,用于显示系统分隔符的命令,不需要任何定义与包含即可直接使用. 在windows下路径分隔符是/(当然/在部分系统上也是可以正常运行的),在li ...
-
orleans发送广播消息
一个client发送消息给orleans, 就只需要掉用Grain的函数就行了. 但是有时候Grain需要发送消息给client, 在orleans里面, 就只能通过Observer来实现. publ ...
-
pm2 官方文档 学习笔记
一.安装 1.安装 npm install pm2 -g 2.更新 npm install pm2 -g && pm2 update pm2 update 是为了刷新 PM2 的守护进 ...
-
Sword libcurl使用
libcurl编译 >> ./configure --prefix=/opt/soft/curl --disable-ldap --disable-ldaps >> make ...
-
ubuntu 16.04 安装PhpMyAdmin
首先,安装mysql $ sudo apt-get install mysql-server $ sudo apt-get install mysql-client 安装时输出root用户的密码 然后 ...
-
FFmpeg的使用&mdash;&mdash;PHP转换视频、截取视频以及JW Player播放器控制
转载:http://blog.csdn.net/zm2714/article/details/7916440 给朋友做的一个项目中,涉及到上传视频.转换视频.自动截取已上传视频内容中的一帧做为缩略图片 ...