c++ - 引用的临时对象的析构函数

标签 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()

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

最佳答案

这与右值引用无关。事实上,如果在整个代码中将 A&& 更改为 const A&the behavior won't change .

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

不要考虑析构函数,考虑对象的生命周期。我个人不知道简单的经验法则(除了“阅读标准”),但这三个规则可能对您有所帮助:

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

关于c++ - 引用的临时对象的析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29205339/

相关文章:

java - 在 C++ 中实现观察者模式

c++ - 用于类似 GUI 的终端导航(vim/lynx 样式)的食谱/教程/库?

c++ - 在析构函数中持有 std::lock_guard 是否安全?

c++ - 在一组 shared_ptr 中找到一个值

c++ - 需要帮助来修复我的代码以执行特定的逻辑

java - 从 TooTallNate/Java-Websockets 调用 libwebsockets 服务器失败

c++ - 为什么节点*左,*右而不是节点*左,右?

c++ - 应该是一个虚拟析构函数?但是怎么办?

java - 如何正确使用dispose()?

c++ - 添加到 vector 的 std::shared_ptr 会导致段错误