如果我有一堂“酒吧”课:
// bar.h
class Bar
{
public:
Bar() { }
};
我转发声明与另一个类“Foo”中的 std::unique_ptr 一起使用:
// foo.h
#include <memory>
class Bar;
class Foo
{
public:
Foo();
private:
std::unique_ptr<Bar> bar_;
};
我将其定义包含在 Foo 的实现文件中:
// foo.cpp
#include "foo.h"
#include "bar.h"
Foo::Foo()
: bar_(new Bar)
{ }
我收到编译时错误“‘sizeof’对不完整类型‘Bar’的无效应用”。
我的理解是从here https://stackoverflow.com/questions/6012157/is-stdunique-ptrt-required-to-know-the-full-definition-of-t and here http://www.codesynthesis.com/~boris/blog/2012/04/04/when-provide-empty-destructor/为了解决这个问题,我可以在 foo.h 中声明 Foo 的析构函数,并将其空定义移至 foo.cpp。我不明白的是,为什么会解决这个问题。我读到 std::unique_ptr 有时需要知道其类型的完整定义。如果我必须包含 bar.h 中的 Bar 以便 unique_ptr 看到它的定义,这对我来说是有意义的。但是 Foo 的析构函数与 Bar 的可见性有什么关系,为什么在 foo.h 中声明 ~Foo() 并在 foo.cpp 中定义它会消除错误?
的析构函数unique_ptr<Bar>
calls Bar::~Bar
当它delete
's the Bar
它拥有。所以~unique_ptr<Bar>
需要看看Bar::~Bar
.
但模板方法仅在使用时实例化。
唯一的 ptr 被破坏Foo
in Foo::~Foo
. If ~Foo
生活在可以看到定义的地方~Bar
, 一切都很好。
如果你让它由编译器生成,它“存在”在声明中Foo
,在它看不到的地方~Bar
.
如果您转发声明它,则执行Foo::~Foo() = default
or Foo::~Foo() {}
in the .cpp
之后归档#include <bar.h>
,它可以看到~Bar
在这一点上~std::unique_ptr<Bar>
叫做`,一切都好。
这在实践中很重要,因为如何Bar
被破坏取决于是否~Bar
是虚拟的,并且如果Bar
有父母,如果~Bar
是私人/受保护的,拨打电话可能是非法的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)