我正在上课STFT
.在标题中编译就好了:
class STFT; // pimpl off to prevent point name clash class Whatever { private: STFT* stft;
这在实施中:
#include "STFT.h" Whatever::Whatever() : stft(new STFT()) { // blah blah } Whatever::~Whatever() { delete stft; // pure evil }
但是,切换到std::unique_ptr
标题中的原始指针,并删除析构函数,我得到
错误:'sizeof'无效应用于不完整类型'STFT'static_assert(sizeof(_Tp)> 0,"default_delete无法删除不完整类型");
但是,如果我只提供一个空的析构函数Whatever::~Whatever(){}
,那么它编译得很好.这让我完全难过.请填写我这个毫无意义的析构函数为我做的事情.
因此,如果我们转到std :: unique_ptr的cppreference文档:
可以为不完整类型T构造std :: unique_ptr,以便于在Pimpl习语中用作句柄.如果使用默认删除器,则必须在调用删除器的代码中完成T,这发生在析构函数,移动赋值运算符和std :: unique_ptr的重置成员函数中.(相反,std :: shared_ptr不能从原始指针构造为不完整类型,但可以在T不完整的情况下销毁).
我们可以在下面的代码中看到:
#includeclass STFT; // pimpl off to prevent point name clash class Whatever { public: ~Whatever() ; private: std::unique_ptr stft; } ; //class STFT{}; Whatever::~Whatever() {} int main(){}
在定义std::unique_ptr
析构函数之前对定义进行定义时,不满足std::unique_ptr
要求,因为这需要析构函数,T
而析构函数又需要T
完成.
因此,在定义时,您的实现文件似乎std::unique_ptr
是完整的,std::shared_ptr
否则创建默认的文件时T
不会完成.