C++11 can-pimpl习语';s impl类具有析构函数?;

C++11 can-pimpl习语';s impl类具有析构函数?;,c++11,effective-c++,C++11,Effective C++,我在有效的现代cpp中学习了pimpl,在做了一些搜索之后,没有人谈论过pimpl习语的impl类的析构函数实现,这是没有必要的吗 //in widget.h #include <memory> class Widget{ public: Widget(); private: struct Impl; std::unique_ptr<Impl> pImpl; }; //in widget.cpp ........ struct Widget::Im

我在有效的现代cpp中学习了pimpl,在做了一些搜索之后,没有人谈论过pimpl习语的impl类的析构函数实现,这是没有必要的吗

//in widget.h
#include <memory>
class Widget{
public:
    Widget();
private:
    struct Impl;
    std::unique_ptr<Impl> pImpl;
};
//in widget.cpp
........
struct Widget::Impl{
  std::string name;                // Widget::Impl
  std::vector<double> data;
};


struct Widget::~Impl()   //error!!!,how can we implement it
{
};
//在widget.h中
#包括
类小部件{
公众:
Widget();
私人:
结构Impl;
std::唯一的ptr pImpl;
};
//在widget.cpp中
........
结构小部件::Impl{
std::string name;//小部件::Impl
std::矢量数据;
};
结构小部件::~Impl()//错误!!!,我们如何实施它
{
};

PIMPL习惯用法的实现接口结构不能声明为类的
私有
字段。此外,在C++中不允许将代码< > UNQuyGOPTR <代码>声明为不完整的数据类型,因此我们必须选择简单的旧指针来声明PIML和手动<代码>新< /代码>和<代码>删除< /代码>。
struct Impl
的析构函数可以在
widget.cpp
中这样定义:

Widget::Impl::~Impl()
{

};
最终代码可能如下所示:

widget.h widget.cpp
struct小部件::Impl
{
Impl();
std::string name;//小部件::Impl
std::矢量数据;
~Impl();
};
//小部件Impl构造函数
小部件::Impl::Impl()
{
}
//小部件Impl析构函数
小部件::Impl::~Impl()
{
};
//小部件构造函数
Widget::Widget():pImpl(nullptr)
{
pImpl=新的Impl();
}
//小部件析构函数
小部件::~Widget()
{
删除pImpl;
pImpl=空PTR;
}
感谢@Retired Ninja的代码帖子,它帮助了我们很多,关键是,我们需要在cpp文件中声明~Impl:

Widget::Widget():pImpl(std::make_unique<Impl>())
{
}

 struct Widget::Impl {
     std::string name;
     std::vector<double> data;
     ~Impl();// need this !!
 };

 Widget::Impl::~Impl(){
 };

 Widget::~Widget() {
 }
Widget::Widget():pImpl(std::make_unique())
{
}
结构小部件::Impl{
std::字符串名;
std::矢量数据;
~Impl();//需要这个!!
};
小部件::Impl::~Impl(){
};
小部件::~Widget(){
}

除其他外,您还缺少
()
。在这种情况下,明确地说,是的,dtor是无用的(字符串和向量都管理它们的内存本身),如果需要,您可以创建析构函数。。。好的类设计通常不需要您自己的析构函数unique,如果我们确保销毁unique的代码所在的点Widget::Impl是一个完整的类型,那么我们可以在定义Widget::Impl之后定义Widget Destructor。这篇博文提供了更多有关这方面的详细信息:
struct Widget::Impl
{
  Impl();
  std::string name;                // Widget::Impl
  std::vector<double> data;

  ~Impl();
};

//Widget Impl Constructor  
Widget::Impl::Impl()
{

}

//Widget Impl Destructor
Widget::Impl::~Impl()
{

};

//Widget Constructor
Widget::Widget() : pImpl(nullptr)
{
    pImpl = new Impl();
}

//Widget Destructor
Widget::~Widget()
{
    delete pImpl;
    pImpl = nullptr;
}
Widget::Widget():pImpl(std::make_unique<Impl>())
{
}

 struct Widget::Impl {
     std::string name;
     std::vector<double> data;
     ~Impl();// need this !!
 };

 Widget::Impl::~Impl(){
 };

 Widget::~Widget() {
 }