我担心使用带有智能指针的不完整类型以及如何删除指针.以下代码是否安全?我认为不会,因为main.cpp会生成Farm的默认析构函数,它不会看到完整的类型.为了安全起见,我想我应该创建一个非内联析构函数来查看完整类型.那是对的吗?
如果我std::vector<Cow>在农场使用它也是一样的吗?
farm.h
class Cow;
struct Farm
{
Farm();
// ~Farm();
std::unique_ptr<Cow> cow;
};
Run Code Online (Sandbox Code Playgroud)
farm.cpp
#include "cow.h"
// cow now complete
Farm::Farm()
{
cow.reset(new Cow);
}
// Farm::~Farm() {}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include "farm.h"
int main()
{
Farm farm;
}
Run Code Online (Sandbox Code Playgroud)
编辑:我尝试使用没有析构函数的Visual Studio进行编译,它说错误C2338:无法删除不完整的类型.我猜这回答了我的问题.
我认为你的代码不应该编译(并且在 gcc 中也不应该编译)
std::unique_ptr<Cow>使用std::default_delete<Cow>,并且std::default_delete<Cow>::operator()对于不完整的类型应该无法实例化Cow。
另请参阅当 unique_ptr 声明的模板类型为不完整类型时,与 auto_ptr 声明不同,unique_ptr 声明是否定义良好?
所以你是对的:你需要确保在类型完整的default_delete<Cow>::operator()地方实例化它。这意味着需要在这样的地方定义 的Cow析构函数。Farm
我刚刚注意到你的主题说“智能指针”,而问题指定了unique_ptr。对于 a 来说,答案会有所不同shared_ptr,因为std::shared_ptr<Cow>::reset()a 是一个函数模板,它捕获传递给它的指针的(静态)类型并存储删除器。因此,您所需要的只是对具有完整类型的shared_ptr调用——析构函数的位置并不重要。resetCow