C++临时性对象的生命周期详细解析
时间:2023-01-22 04:26:01
有关临时对象的生命周期有三种情况:
1)一般情况:临时性对象的被摧毁,应该是对完整表达式(full-expression)求值过程中的最后一个步骤。该完整表达式造成临时对象的产生。
实例代码如下:
#include <iostream>
using namespace std;
class A
{
public:
A(int i): m_i(i)
{
cout << "A(): " << m_i << endl;
}
~A()
{
cout << "~A(): " << m_i << endl;
}
A operator+(const A& rhs)
{
cout << "A operator+(const A& rhs)" << endl;
return A(m_i + rhs.m_i);
}
int m_i;
};
int main()
{
A a1(1), a2(2);
a1 + a2;
cout << "------------------------------------" << endl; //运行到这里,a1 + a2产生的临时变量已经被释放
return 0;
}
运行结果为:
2)凡含有表达式执行结果的临时性对象,应该存留到object的初始化操作完成为止。
示例代码如下:
#include <iostream>
using namespace std;
class A
{
public:
A(int i = 0): m_i(i)
{
cout << "A(): " << m_i << endl;
}
~A()
{
cout << "~A(): " << m_i << endl;
}
A operator+(const A& rhs)
{
cout << "A operator+(const A& rhs)" << endl;
return A(m_i + rhs.m_i);
}
A& operator=(const A& rhs)
{
cout << "A& operator=(const A& rhs)" << endl;
m_i += rhs.m_i;
return *this;
}
int m_i;
};
int main()
{
A a1(1), a2(2);
A a3;
a3 = a1 + a2; //a1 + a2产生的临时变量在a3的赋值操作完成后,才释放
return 0;
}
运行结果为:
3)如果一个临时性对象被绑定于一个reference,对象将残留,直到被初始化之reference的生命结束,或直到临时对象的生命范畴(scope)结束——视哪一种情况先到达而定。
示例代码如下:
#include <iostream>
using namespace std;
class A
{
friend ostream& operator<<(ostream& os, const A&);
public:
A()
{
}
A(const A&)
{
cout << "A(const A&)" << endl;
}
~A()
{
cout << "~A()" << endl;
}
};
ostream& operator<<(ostream& os, const A&)
{
os << "ostream& operator<<(ostream& os, const A&)" << endl;
return os;
}
const A& f(const A& a)
{
return a;
}
int main(int argc, char* argv[])
{
{
const A& a = A();
cout << "-------------------" << endl;
}//直到被初始化之reference的生命结束
cout << f(A()) << endl; //直到临时对象的生命范畴(scope)结束:
//临时对象的const引用在f的参数上(而不是返回值)。
//这个引用在f()返回的时候就结束了,但是临时对象未必销毁。
cout << "-------------------" << endl;
return 0;
}
运行结果:
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
android实现背景音乐播放功能
Java利用蒙特卡洛方法求解圆周率π值
![](https://img.aspxhome.com/file/2023/3/91123_0s.png)
Mybatis日志参数快速替换占位符工具的详细步骤
详解java中jvm虚拟机栈的作用
C#中的虚方法和抽象方法的运用
![](https://img.aspxhome.com/file/2023/5/122705_0s.png)
java8 forEach结合Lambda表达式遍历 List操作
Java动态 代理的应用详解
C#实现协同过滤算法的实例代码
Android 使用Vitamio打造自己的万能播放器(10)—— 本地播放 (缩略图、视频信息、视频扫描服务)
![](https://img.aspxhome.com/file/2023/1/126791_0s.png)
C#实现视频的批量剪辑功能
![](https://img.aspxhome.com/file/2023/3/96423_0s.png)
java封装及四种权限修饰符详解
![](https://img.aspxhome.com/file/2023/6/132086_0s.png)
Java并发编程之栅栏(CyclicBarrier)实例介绍
myBatis实现三 级嵌套复杂对象的赋值问题
Spring-Security对HTTP相应头的安全支持方式
关于Java中增强for循环使用的注意事项
![](https://img.aspxhome.com/file/2023/7/63307_0s.png)
Android 8.0的缓存大小和缓存清理接口方法
Android实现ImageView阴影和图层效果
![](https://img.aspxhome.com/file/2023/1/125411_0s.jpg)
Java for循环的妙用之鸡兔同笼问题
![](https://img.aspxhome.com/file/2023/7/96267_0s.png)
Java中如何使用Response重定向
![](https://img.aspxhome.com/file/2023/9/71249_0s.png)