我在类里面拉皮条STFT
.在 header 中用这个编译就好了:
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<STFT> stft;
在 header 中的原始指针上,并删除析构函数,我得到 p>
error: invalid application of 'sizeof' to an incomplete type 'STFT'
static_assert(sizeof(_Tp) > 0, "default_delete can not delete incomplete type");
但如果我只是提供一个空的析构函数 Whatever::~Whatever(){}
,然后编译正常。这让我完全难住了。请告诉我这个无意义的析构函数为我做了什么。
如果我们转到 std::unique_ptr
的 cppreference 文档:
std::unique_ptr
may be constructed for an incomplete type T
, such as
to facilitate the use as a handle in the Pimpl idiom. If the default
deleter is used, T
must be complete at the point in code where the
deleter is invoked, which happens in the destructor, move assignment
operator, and reset member function of std::unique_ptr
. (Conversely,
std::shared_ptr
can't be constructed from a raw pointer to incomplete
type, but can be destroyed where T
is incomplete).
我们可以在下面的代码中看到:
#include <memory>
class STFT; // pimpl off to prevent point name clash
class Whatever
{
public:
~Whatever() ;
private:
std::unique_ptr<STFT> stft;
} ;
//class STFT{};
Whatever::~Whatever() {}
int main(){}
如果在定义 Whatever
的析构函数之前注释了 STFT
的定义,则不满足要求,因为这需要 stft
的析构函数这反过来又需要 STFT
才能完成。
因此,当 Whatever::~Whatever()
被定义时,您的实现文件STFT
似乎很可能是完整的,否则默认一个是在 STFT
不完整的情况下创建的。