我不小心写了一个像
这样的陈述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);
我没有通过谷歌找到任何关于这种行为的解释,所以我希望也许有人可以向我解释窗帘背后发生了什么。
答案 0 :(得分:4)
DoStuff
不是虚拟的,不会访问您对象的任何成员,因此您可以放弃调用它(我很确定这是未指定的行为)。 unique_ptr
的默认构造函数将其初始化为nullptr
,因此它不会自行分配任何内存。
哦,析构函数当然不会被调用,因为unique_ptr不会在nullptr
上调用它的删除器。
答案 1 :(得分:4)
您的程序显示未定义的行为。 “似乎工作”是未定义行为的一种可能表现形式。它在道德上等同于
Thing* p = NULL;
p->DoStuff();
我预测它也会编译运行。使用DoStuff
NULL
指针调用this
- 但它实际上并未使用this
,这就是为什么它不会像您预期的那样崩溃和刻录。