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

时间:2015-03-23 07:48:27

标签: c++ destructor c++14

举个例子:

#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()

什么是语义规则:标准段落的可思考缩写,它紧凑地总结了上述代码示例中析构函数行为的差异?我经常面对通过“具有一些(非显然相关)特征”或“具有一些固有属性”陈述而制定的“惯用规则”,例如“如果它有一个名字,那么它就是一个左值”。有类似的东西吗?

1 个答案:

答案 0 :(得分:4)

这与右值参考无关。实际上,如果您在整个代码中将A&&更改为const A&the behavior won't change

可能您的混淆是由std::move()函数的名称引起的。它实际上并没有移动任何东西,它只是将其参数转换为右值参考。

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

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