2011-12-23 15 views
5
// 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’) 

上記のコンパイルエラーの解決方法は、手動でデストラクタを提供することです。次のように示された理由は以下のとおりです。PIMPLにデストラクタを提供する必要があります

あなたはまだ手動でデストラクタを定義するために覚えておく必要があります。理由 は、コンパイラが暗黙のデストラクタを生成するときに、 型のimplが不完全であるため、そのデストラクタが呼び出されないということです。

質問>私はまだ上記のアイデアを吸収する難しさを持っているし、私たちがここに手動デストラクタを提供しなければならない理由はほとんど詳細を知りたいのです。

あなた

答えて

7

TLありがとう; DRは、明示的なデストラクタを宣言し、(いないヘッダファイル内の)コードモジュールに実装します。

デストラクタを作成しない場合、コンパイラは、このクラスのオブジェクトを破棄しようとするすべての変換単位に空の自動デストラクタを作成します。クラスヘッダに空のインラインデストラクタを定義した場合、これと同等の動作が得られます。

デストラクターがすべてのクラスのフィールドのデストラクタの呼び出しにも責任を負うため、これによりエラーが発生します。これは - 順番に - メソッドテンプレートboost::scoped_ptr<impl>::~scoped_ptr();のインスタンス化が必要です。それが唯一の楽しみ(そのスコープ内で宣言されたタイプimplのオブジェクトを削除しようとするため、このテンプレートは、今度は、そのインスタンス化することはできません、あなたは、このオブジェクトを削除する方法を知っている完全な定義を必要としています。


implの定義をあるので、scoped_ptrをのデストラクタが正常にインスタンス化することができますが、ヘッダーに非インラインコンストラクタを宣言した場合、そのコードは唯一pimpl_sample.cppで生成される大藤、。

他の翻訳単位のみコールpimpl_sampleのデストラクタを外部メソッドとして生成する必要がなく、scoped_ptrをインスタンス化する必要はありません彼ら自身のデストラクタ。

+0

私は簡単な要約を追加しました。自由に編集/元に戻してください。 – krlmlr

関連する問題