引用的临时对象的析构函数

Destructor of referenced temporary object

本文关键字:析构函数 临时对象 引用      更新时间:2023-10-16

给定示例:

#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()函数的名称引起的。它实际上并没有移动任何东西,只是将其参数转换为右值引用。

不要考虑析构函数,要考虑对象的生存期。就我个人而言,我不知道一个简单的经验法则(除了"阅读标准"),但这三条规则可能会对你有所帮助:

  1. 静态对象(基本上)具有整个程序的生存期
  2. 如果从函数返回的临时对象没有绑定到任何东西,那么当整个表达式执行结束时,它的生存期就结束了
  3. 如果从函数返回的临时对象绑定到某个引用,则其生存期将延长到该引用的生存期