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