C++ 如何在具有不完整的前向声明类的头文件中声明智能指针?

C++ 如何在具有不完整的前向声明类的头文件中声明智能指针?,c++,c++11,smart-pointers,forward-declaration,C++,C++11,Smart Pointers,Forward Declaration,我有一个带有前向声明类的头,我想在其中声明一些智能指针成员。然而,由于智能指针模板类型在声明时在技术上是不完整的,因此我得到了关于sizeof不能用于唯一指针的编译错误。我是否必须将实现头拉入类的头中,而不是向前声明它们,或者我是否可以为我的向前声明提供一个额外的存根来满足智能指针 例如,这是头文件: #包括 名称空间N{ 甲级; 类所有者{ std::唯一的我的成员; } } 这是源文件: #include "A.H" class Owner{ Owner()

我有一个带有前向声明类的头,我想在其中声明一些智能指针成员。然而,由于智能指针模板类型在声明时在技术上是不完整的,因此我得到了关于sizeof不能用于唯一指针的编译错误。我是否必须将实现头拉入类的头中,而不是向前声明它们,或者我是否可以为我的向前声明提供一个额外的存根来满足智能指针

例如,这是头文件:

#包括
名称空间N{
甲级;
类所有者{
std::唯一的我的成员;
}
}
这是源文件:

#include "A.H"

class Owner{
    Owner() {
        myMember = std::make_unique<A>("arg1", "arg2");
    }
}
#包括“A.H”
类所有者{
所有者(){
myMember=std::使_唯一(“arg1”、“arg2”);
}
}
我不希望将依赖关系泄露给包括我的头的每个人,这就是为什么在我使用原始指针时,这些类最初是向前声明的

如何在具有不完整的前向声明类的头文件中声明智能指针

通过定义构造函数、析构函数和其他函数,这些函数依赖于头外部和单独转换单元内的指向类的完整定义

我是否必须将实现头拉入类的头中

不需要。只有当您没有像我所描述的那样在类定义之外定义成员函数时,才需要这样做


例如:

struct Owner {
    std::unique_ptr<A> myMember;

    Owner();
    ~Owner();
    Owner(Owner&&);
    Owner& operator=(Owner&&);
};

class A {};

Owner::Owner() = default;
Owner::~Owner() = default;
Owner::Owner(Owner&&) = default;
Owner& Owner::operator=(Owner&&) = default;
结构所有者{ std::唯一的我的成员; 所有者(); ~Owner(); 业主(业主和&); 所有者和经营者=(所有者和经营者); }; A类{}; 所有者::所有者()=默认值; 所有者::~Owner()=默认值; 所有者::所有者(所有者&)=默认值; 所有者和所有者::运算符=(所有者和)=默认值; 如何在具有不完整的前向声明类的头文件中声明智能指针

通过定义构造函数、析构函数和其他函数,这些函数依赖于头外部和单独转换单元内的指向类的完整定义

我是否必须将实现头拉入类的头中

不需要。只有当您没有像我所描述的那样在类定义之外定义成员函数时,才需要这样做


例如:

struct Owner {
    std::unique_ptr<A> myMember;

    Owner();
    ~Owner();
    Owner(Owner&&);
    Owner& operator=(Owner&&);
};

class A {};

Owner::Owner() = default;
Owner::~Owner() = default;
Owner::Owner(Owner&&) = default;
Owner& Owner::operator=(Owner&&) = default;
结构所有者{ std::唯一的我的成员; 所有者(); ~Owner(); 业主(业主和&); 所有者和经营者=(所有者和经营者); }; A类{}; 所有者::所有者()=默认值; 所有者::~Owner()=默认值; 所有者::所有者(所有者&)=默认值; 所有者和所有者::运算符=(所有者和)=默认值;
请粘贴错误消息这是否回答了您的问题?请粘贴错误消息这是否回答了您的问题?在发布我的问题后,我意识到标题中实际上有
~Owner()=default
。我是否需要在源文件中只包含一个空的析构函数,而不是让编译器在标题中生成它?@cabbagesoup是的。我在发布问题后意识到,标题中实际上包含了
~Owner()=default
。我是否需要在源文件中有一个空的析构函数,而不是让编译器在头文件中生成它?@cabbagesoup Yes。