必须在PIMPL中提供析构函数 //main\u pimpl\u sample.cpp #包括“pimpl_sample.hpp” 使用名称空间std; int main() { pimpl_样本; 返回0; } //pimpl_sample.cpp #包括“pimpl_sample.hpp” 结构pimpl_示例::impl{ }; pimpl_样本::pimpl_样本() :pimpl_u2;(新impl){ } //pimpl_样本::~pimpl_样本() //如果遗漏,则会导致问题 // {} //pimpl_sample.hpp #如果!已定义(PIMPL_样本) #定义PIMPL_样本 #包括 类pimpl_样本{ 结构impl; boost::作用域\u ptr pimpl; 公众: pimpl_样本(); //~pimpl_sample();如果遗漏,会导致问题 虚空做某事; }; #恩迪夫 ~/Documents/C++/boost$g++--版本 g++(Ubuntu/Linaro 4.5.2-8ubuntu4)4.5.2 ~/Documents/C++/boost$g++-o main\u pimpl\u sample main\u pimpl\u sample.cpp pimpl\u sample.hpp 在/usr/include/boost/smart_ptr/scoped_ptr.hpp:15:0中包含的文件中, 从/usr/include/boost/scoped_ptr.hpp:14, 来自pimpl_样本。hpp:6, 来自main_pimpl_sample.cpp:2: /usr/include/boost/checked_delete.hpp:在函数“void boost::checked_delete(T*)[with T=pimpl_sample::impl]”中: /usr/include/boost/smart_ptr/scoped_ptr.hpp:80:9:从“boost::scoped_ptr::~scoped_ptr()[with T=pimpl_sample::impl]实例化” pimpl_sample.hpp:8:20:从此处实例化 /usr/include/boost/checked_delete.hpp:32:58:错误:“sizeof”对不完整类型“pimpl_sample::impl”的应用无效 /usr/include/boost/checked_delete.hpp:32:58:错误:创建大小为负的数组('-0x00000000000000001'))

必须在PIMPL中提供析构函数 //main\u pimpl\u sample.cpp #包括“pimpl_sample.hpp” 使用名称空间std; int main() { pimpl_样本; 返回0; } //pimpl_sample.cpp #包括“pimpl_sample.hpp” 结构pimpl_示例::impl{ }; pimpl_样本::pimpl_样本() :pimpl_u2;(新impl){ } //pimpl_样本::~pimpl_样本() //如果遗漏,则会导致问题 // {} //pimpl_sample.hpp #如果!已定义(PIMPL_样本) #定义PIMPL_样本 #包括 类pimpl_样本{ 结构impl; boost::作用域\u ptr pimpl; 公众: pimpl_样本(); //~pimpl_sample();如果遗漏,会导致问题 虚空做某事; }; #恩迪夫 ~/Documents/C++/boost$g++--版本 g++(Ubuntu/Linaro 4.5.2-8ubuntu4)4.5.2 ~/Documents/C++/boost$g++-o main\u pimpl\u sample main\u pimpl\u sample.cpp pimpl\u sample.hpp 在/usr/include/boost/smart_ptr/scoped_ptr.hpp:15:0中包含的文件中, 从/usr/include/boost/scoped_ptr.hpp:14, 来自pimpl_样本。hpp:6, 来自main_pimpl_sample.cpp:2: /usr/include/boost/checked_delete.hpp:在函数“void boost::checked_delete(T*)[with T=pimpl_sample::impl]”中: /usr/include/boost/smart_ptr/scoped_ptr.hpp:80:9:从“boost::scoped_ptr::~scoped_ptr()[with T=pimpl_sample::impl]实例化” pimpl_sample.hpp:8:20:从此处实例化 /usr/include/boost/checked_delete.hpp:32:58:错误:“sizeof”对不完整类型“pimpl_sample::impl”的应用无效 /usr/include/boost/checked_delete.hpp:32:58:错误:创建大小为负的数组('-0x00000000000000001')),c++,pimpl-idiom,C++,Pimpl Idiom,上述编译错误的解决方案是手动提供析构函数。原因如下: 您必须记住手动定义析构函数;原因 在编译器生成隐式析构函数时 类型impl不完整,因此未调用其析构函数 问题>我仍然难以理解上述想法,我想知道一点细节,为什么我们必须在这里提供手动析构函数 多谢各位 TL;DR声明一个显式析构函数,并在代码模块(而不是头文件)中实现它 如果不创建析构函数,那么编译器会在每个试图销毁此类对象的翻译单元中创建一个空的自动析构函数。如果在类头中定义了一个空的内联析构函数,则会得到相同的行为 这会导致一个错误,因为析

上述编译错误的解决方案是手动提供析构函数。原因如下:

您必须记住手动定义析构函数;原因 在编译器生成隐式析构函数时 类型impl不完整,因此未调用其析构函数

问题>我仍然难以理解上述想法,我想知道一点细节,为什么我们必须在这里提供手动析构函数

多谢各位

TL;DR声明一个显式析构函数,并在代码模块(而不是头文件)中实现它

如果不创建析构函数,那么编译器会在每个试图销毁此类对象的翻译单元中创建一个空的自动析构函数。如果在类头中定义了一个空的内联析构函数,则会得到相同的行为

这会导致一个错误,因为析构函数还负责调用所有类字段的析构函数,这些字段需要实例化方法模板
boost::scoped_ptr::~scoped_ptr()。然后,无法实例化此模板,因为它尝试删除类型为
impl
的对象,该对象仅在该范围内被正向声明(您需要完整的定义才能知道如何删除此对象)


OTOH,如果在头中声明非内联构造函数,则其代码仅在
pimpl\u sample.cpp
中生成,其中还包含
impl
的定义,因此可以成功实例化作用域ptr的析构函数


其他翻译单元则只调用
pimpl\u sample
的析构函数作为外部方法,因此它们不需要生成它并自己实例化
作用域的ptr
的析构函数。

我添加了一个简短的摘要,请随意编辑/还原。
// main_pimpl_sample.cpp
#include "pimpl_sample.hpp"

using namespace std;

int main()
{
  pimpl_sample p;

  return 0;
}

// pimpl_sample.cpp 

#include "pimpl_sample.hpp"

struct pimpl_sample::impl {
};

pimpl_sample::pimpl_sample()
  : pimpl_(new impl) {
}

// pimpl_sample::~pimpl_sample()
// cause problem if missed
// {}


// pimpl_sample.hpp

#if !defined (PIMPL_SAMPLE)
#define PIMPL_SAMPLE

#include <boost/scoped_ptr.hpp>

class pimpl_sample {
  struct impl;
  boost::scoped_ptr<impl> pimpl_;

public:
  pimpl_sample();
  //~pimpl_sample(); cause problem if missed
  void do_something();
};

#endif


~/Documents/C++/boost $ g++ --version
g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2

~/Documents/C++/boost $ g++ -o main_pimpl_sample main_pimpl_sample.cpp pimpl_sample.cpp pimpl_sample.hpp
In file included from /usr/include/boost/smart_ptr/scoped_ptr.hpp:15:0,
                 from /usr/include/boost/scoped_ptr.hpp:14,
                 from pimpl_sample.hpp:6,
                 from main_pimpl_sample.cpp:2:
/usr/include/boost/checked_delete.hpp: In function ‘void boost::checked_delete(T*) [with T = pimpl_sample::impl]’:
/usr/include/boost/smart_ptr/scoped_ptr.hpp:80:9:   instantiated from ‘boost::scoped_ptr<T>::~scoped_ptr() [with T = pimpl_sample::impl]’
pimpl_sample.hpp:8:20:   instantiated from here
/usr/include/boost/checked_delete.hpp:32:58: error: invalid application of ‘sizeof’ to incomplete type ‘pimpl_sample::impl’ 
/usr/include/boost/checked_delete.hpp:32:58: error: creating array with negative size (‘-0x00000000000000001’)