I wrote accidentally a statement like

std::unique_ptr<Thing> m_thing; 
m_thing->DoStuff();

instead of

std::unique_ptr<Thing> m_thing(new Thing);
m_thing->DoStuff();

the first example compiles and run, which doesn't make any sense to me because m_thing is not pointing to any object. Here a slightly bigger code example.

#include <iostream>
#include <memory>
class Thing
    {
    public:
    ~Thing(){ std::cout << "destructor of class Thing\n"; }
    void DoStuff(){ std::cout << "doing stuff\n";  }
    };

void Foo()
   {
   std::unique_ptr<Thing> m_thing; 
    m_thing->DoStuff();  //why does this work, since i suppose m_thing to be empty?
    }

int main()
    {
    Foo();
    std::cout << "after Foo()\n"; 
    std::cin.get(); 
    return 0; 
    }

Why can the "empty" m_thing unique_ptr invoke the DoStuff()-Method of the Thing-class? i noticed also, that the destructor of Thing-class never gets invoked when declaring m_thing with

std::unique_ptr<Thing> m_thing; 

instead of

std::unique_ptr<Thing> m_thing(new Thing);

I didn't found any explanation of this behaviour via google, so i hope maybe someone can explain to me what is happening here behind the curtains.

有帮助吗?

解决方案

Your program exhibits undefined behavior. "Seems to work" is one possible manifestation of undefined behavior. It's morally equivalent to

Thing* p = NULL;
p->DoStuff();

which I predict would also compile and run. DoStuff is called with NULL for this pointer - but it doesn't actually use this, that's why it doesn't crash and burn as you expect.

其他提示

DoStuff isn't virtual and doesn't access any members of your object, so you can get away with calling it (I'm pretty sure this is unspecified behavior though). The default constructor for unique_ptr initializes it to nullptr, so it doesn't allocate any memory on its own.

Oh, and the destructor of course doesn't get called because unique_ptr doesn't invoke its deleter on nullptrs.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top