引用的临时对象的析构函数
Destructor of referenced temporary object
给定示例:
#include <iostream>
#include <cstdlib>
#define PRINT_NAME { std::cout << __PRETTY_FUNCTION__ << std::endl; }
namespace
{
struct A
{
A() { PRINT_NAME; }
~A() { PRINT_NAME; }
};
A f() { return {}; }
A b;
A && g() { return std::move(b); }
}
int
main()
{
std::cout << "------------------" << std::endl;
{
f();
std::cout << 1 << std::endl;
}
std::cout << "------------------" << std::endl;
{
A && a = f();
// or A const & a = f(); as mentioned in below discussion
std::cout << 2 << std::endl;
}
std::cout << "------------------" << std::endl;
{
A && a = g();
std::cout << 3 << std::endl;
}
std::cout << "------------------" << std::endl;
return EXIT_SUCCESS;
}
其输出(clang 3.5.0):
(anonymous namespace)::A::A()
------------------
(anonymous namespace)::A::A()
(anonymous namespace)::A::~A()
1
------------------
(anonymous namespace)::A::A()
2
(anonymous namespace)::A::~A()
------------------
3
------------------
(anonymous namespace)::A::~A()
语义规则是什么:标准段落的一个可想象的缩写,它紧凑地总结了关于上述代码示例的析构函数行为的差异?我经常面临通过"具有某些(不明显相关的)特征"或"具有某些固有属性"语句制定的"惯用规则",例如"如果它有名称,那么它就是左值"。有类似的东西吗?
这与右值引用无关。事实上,如果在整个代码中将A&&
更改为const A&
,则行为不会改变。
您的困惑可能是由std::move()
函数的名称引起的。它实际上并没有移动任何东西,只是将其参数转换为右值引用。
不要考虑析构函数,要考虑对象的生存期。就我个人而言,我不知道一个简单的经验法则(除了"阅读标准"),但这三条规则可能会对你有所帮助:
- 静态对象(基本上)具有整个程序的生存期
- 如果从函数返回的临时对象没有绑定到任何东西,那么当整个表达式执行结束时,它的生存期就结束了
- 如果从函数返回的临时对象绑定到某个引用,则其生存期将延长到该引用的生存期
相关文章:
- 什么时候调用组成单元对象的析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- C++析构函数调用两次,堆栈分配的复合对象
- 如何从 Gtk::窗口调用派生对象的析构函数
- 为什么数组中对象的析构函数在被另一个对象替换时不被调用?
- 为什么为未删除的对象调用析构函数?
- 对象的构造函数和析构函数
- 虚拟析构函数将对象移出 rodata 部分
- 为什么我可以访问已删除但在C++中具有虚拟析构函数的对象?
- C++中使用构造函数和析构函数的对象计数器
- 删除具有受保护析构函数的对象
- C++ 如何处理带有破坏状态的析构函数的对象副本
- 引用的临时对象的析构函数
- 为什么析构函数在对象引用作为参数传递时函数范围结束后调用
- 为什么允许我声明一个带有已删除析构函数的对象
- c++函数可以返回带有构造函数和析构函数的对象
- 删除具有受保护析构函数的对象
- Unique_ptr析构函数表示对象从未被分配过
- 如何为C++中函数返回的临时对象调用析构函数