I suspect I don’t understand something about move semantics. Given the following code I would expect the debugger (MSVC2010SP1) to call Proxy’s members in the following order:
Proxy(Resource*)constructing the temporary ingetProxyProxy(Proxy&& other)move constructingp~Proxy()destructing the empty shell of the temporary that got its guts taken by move-
~Proxy() pgoes out of scopeclass 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
Instead the order is:
Proxy(Proxy*)~Proxy()//this already callsclose()earlier than expectedProxy(Proxy&& other)//moving after destruction givesp.pResource_a value ofnullptr~Proxy()//pgoes out of scope
This makes no sense to me. What I’m trying to do is track the lifetime of the proxy class passing the job of closing the resource via the move constructor from one object to another.
getProxy()returns a reference to a temporary, which goes out of scope at function end and results in a dangling reference.