返回临时值(rvalue)时,为什么析构函数在move构造函数之前调用

odi*_*erd 2 c++ temporary move-semantics

我怀疑我对移动语义一无所知。给定以下代码,我希望调试器(MSVC2010SP1)按以下顺序调用Proxy的成员:

  • Proxy(Resource*) 在临时建筑 getProxy
  • Proxy(Proxy&& other) 搬家 p
  • ~Proxy() 破坏临时实体的空壳,使之胆怯
  • ~Proxy() p 超出范围

    class Resource
    {
        void open(){}
    public:
        void close(){}
        Proxy && getProxy();
    };
    class Proxy
    {
        Resource *pResource_;
        Proxy(const Proxy& other); //disabled
        Proxy& operator=(const Proxy& other); //disabled
    public:
        Proxy(Resource *pResource):pResource_(pResource){}
        Proxy(Proxy&& other):pResource_(other.pResource_){other.pResource_ = nullptr;}
        ~Proxy()
        {
            if(pResource_)
                pResource_->close();
            pResource_ = nullptr;
        }
    };
    
    Proxy && Resource::getProxy()
    {
            open();
            return Proxy(this);
    }
    
    //somewhere else, lets say in main()
    Resource r;
    {
        auto p = r.getProxy(); 
    }   // p goes out of scope
    
    Run Code Online (Sandbox Code Playgroud)

相反,顺序为:

  • Proxy(Proxy*)
  • ~Proxy() //此调用close()早于预期
  • Proxy(Proxy&& other) //销毁后移动p.pResource_的值为nullptr
  • ~Proxy() // p超出范围

这对我来说毫无意义。我想做的是跟踪代理类的生命周期,该类通过将构造函数从一个对象移动到另一个对象来关闭资源。

Rei*_*ica 5

getProxy() 返回对临时变量的引用,该临时变量超出函数范围的范围,并导致悬挂的引用。