为什么unique_ptr::~unique_ptr需要T的定义?

2024-04-21

如果我有一堂“酒吧”课:

// 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(使用前将#替换为@)

为什么unique_ptr::~unique_ptr需要T的定义? 的相关文章