This question already has answers here:
std::unique_ptr with an incomplete type won't compile
(6个答案)
7年前关闭。
让我们考虑以下示例(使用c++ 11)
A.hpp:
main.cpp:
使用默认构造函数和析构函数。不编译。发生以下错误:
当使用boost::scoped_ptr而不是std::unique_ptr时,会发生类似的错误。我是否正确理解这一点-就是说,AImpl的正向声明还不够?
添加构造函数和析构函数时,一切正常。是什么原因?是否因为内联默认值而看不到AImpl的大小?在添加构造函数和析构函数时,编译器会假设这些定义知道AImpl的大小?
(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