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++真心麻烦…
本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5223094.html,如需转载请自行联系原作者