匿名对象生存周期什么是匿名对象?匿名对象简单的说就是没有名字的对象,和临时对象是完全不相同的。比如交换两个变量a、b的值通常做法是使用一个临时变量c
int a=1,b=2,c;
c=a;
a=b;
b=c;
这样的一个过程这里的c在这个过程之后就不在需要,但交换过程中就须要这样一个对象存在,那么这个c就是一个临时对象。而匿名对象则根本没有名字,这点在C++中很常见。比如你要连接一个两个字符串然后输出。
int main()
{
string a("aaa"),b("bbb");
printf("%s",(a+b).c_str() );
return 0;
}
这个时候输出的就是aaabbb这样的一个字符串,当然原来的变量a,b都没有任何变化。这是因为string类重载了+号函数大致如下(当然STL中的不是这个样子,我这样是为了简便,但功能是相同的)
string operator+(string& opt1,string& opt2);
该函数返回一个string对象,而例子程序中并没有出现这个对象,但这个对象却却实实存在着。编译器大致会将程序代码处理成这个样子。其中_1234897erw_是我随便打的名字实际上编译器可能随机生成一个名字,这个对象的有效范围就是{}之中的范围。简单的说就是匿名对象存在的当前行是有效的,一旦到了下一行,这个对象就已经无效。
int main()
{
string a::a("aaa");
string b::b("bbb");
{
string _1234897erw_ = a+b;构造对象
printf("%s",_1234897erw_.c_str() );
_1234897erw_::~_1234897erw_();析构对象
}
b::~b();
a::~a();
return 0;
}
关于临时变量很常见的错误就是
int main()
{
string a("aaa"),b("bbb");
const char* p = (a+b).c_str();
printf("%s", p);
return 0;
}
虽然这样在很多编译器上可以正常输出结果,但这样的做法是错误的。按照匿名变量的生存范围来说p所指向的内容只在当前行有效,一旦到了printf的这一行,p所指向的内容已经无效。所以输出的内容也是不正确的,虽然有时候可以正常输出。
为什么会正常输出,这依赖于库的实现。在匿名string析构的时候,会将所分配的内存空间释放,然而这个释放并不是将原来的内容清除,仅仅是将这块内存空间标志为可用,里面的内容可能不清除(效率因素)。这块内存的内容不清除的话,还是能够得到其内容的(取内容之需要一个*操作符),但这块内存不是你所拥有的,这个时候正确也只是运气。
转载出处:http://blog.csdn.net/akirya/archive/2007/03/13/1527541.aspx