std :: unique_ptr <t>而不在堆上分配内存</t>

时间:2014-02-15 15:27:08

标签: c++11 unique-ptr

我不小心写了一个像

这样的陈述
std::unique_ptr<Thing> m_thing; 
m_thing->DoStuff();

而不是

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

第一个例子编译并运行,这对我没有任何意义,因为m_thing没有指向任何对象。这里有一个稍大的代码示例。

#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; 
    }

为什么“empty”m_thing unique_ptr可以调用DoStuff() - Thing-class的方法? 我还注意到,在声明m_thing时,Thing-class的析构函数永远不会被调用 与

std::unique_ptr<Thing> m_thing; 

而不是

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

我没有通过谷歌找到任何关于这种行为的解释,所以我希望也许有人可以向我解释窗帘背后发生了什么。

2 个答案:

答案 0 :(得分:4)

DoStuff不是虚拟的,不会访问您对象的任何成员,因此您可以放弃调用它(我很确定这是未指定的行为)。 unique_ptr的默认构造函数将其初始化为nullptr,因此它不会自行分配任何内存。

哦,析构函数当然不会被调用,因为unique_ptr不会在nullptr上调用它的删除器。

答案 1 :(得分:4)

您的程序显示未定义的行为。 “似乎工作”是未定义行为的一种可能表现形式。它在道德上等同于

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

我预测它也会编译运行。使用DoStuff NULL指针调用this - 但它实际上并未使用this,这就是为什么它不会像您预期的那样崩溃和刻录。

相关问题