This question already has answers here:
std::unique_ptr with an incomplete type won't compile

(6个答案)


7年前关闭。




让我们考虑以下示例(使用c++ 11)

A.hpp:
#include <memory>
class A
{
  public:
    //A();
    //~A();

  private:
    struct AImpl;
    std::unique_ptr<AImpl> pImpl;
};

main.cpp:
#include "A.hpp"

int main()
{
    A a;
}

使用默认构造函数和析构函数。不编译。发生以下错误:



当使用boost::scoped_ptr而不是std::unique_ptr时,会发生类似的错误。我是否正确理解这一点-就是说,AImpl的正向声明还不够?

添加构造函数和析构函数时,一切正常。是什么原因?是否因为内联默认值而看不到AImpl的大小?在添加构造函数和析构函数时,编译器会假设这些定义知道AImpl的大小?

最佳答案

unique_ptr析构函数需要知道AImpl的完整定义,因为它会删除它。所以问题是,unique_ptr析构函数在哪里?这是一个模板,所以问题是关于实例化点。

析构函数在首次使用时被实例化。包含类的构造函数和析构函数都使用它(如果构造函数的主体抛出异常,则构造函数需要使用它)。因此,将unique_ptr析构函数实例化到放置A的构造函数或析构函数的位置,以先到者为准。

如果您默认这些特殊成员,则它们将在类主体之后立即生成,即在 header 中,其中AImpl的大小未知。

如果改为在类中声明它们,然后在=default的完整定义之后将定义(您可以将这些定义.cpp这些定义)放在AImpl中,则在那里实例化unique_ptr析构函数。

关于c++ - 具有智能PTR的Pimpl-为什么需要构造器/析构器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21699201/

10-13 08:30