2011-12-29 10 views
2

私はboost::intrusive_ptrを参照カウントスマートポインタとして使用しています。intrusive_ptrリファレンスカウントとインクルードサイクルのための基本クラスを使用hell

http://www.codeproject.com/KB/stl/boostsmartptr.aspx#intrusive_ptr%20-%20lightweight%20shared%20pointer

それはそれから継承し、新しいリファレンスカウントクラスの宣言を簡素化するため、これは、良いアイデアだ:私はこのようなものを使用しています。問題は、前方宣言に伴い発生します。参照カウントを処理する2つのメソッドは、型がCRefCountedから継承するかどうかを知る必要があるため、クラス定義でまだ宣言されていない型へのポインタを使用したい場所はたくさんあり、不可能です。

私がintrusive_ptrの宣言の前に依存関係を含めると、それは問題ありませんが、その後、私は多くの循環インクルードを取得します。

このシナリオをどのように扱いますか?

+0

少し虚偽ですが、仮想デストラクタを定義していないため、リンクにCRefCountedクラスに深刻な欠陥があります。 – Timo

答えて

0

私はこれまで同様のRefCountedベースクラスを使用していましたが、なぜこのような問題が起きるのか不思議に思っていました。それは、ソースファイルで実装の詳細を隠す傾向があるからです。クラスBの次のヘッダーファイルを考えてみましょう:

//File: B.h 
#include <boost/intrusive_ptr.hpp> 

class A; 

class B 
{ 
public: 
    B(); 
    ~B(); 
    boost::intrusive_ptr<A> foo(); 
    void foo2(const boost::intrusive_ptr<A> p); 
    boost::intrusive_ptr<A> p; 
}; 

それは動作しますが、それはintrusive_ptr使用しているにもかかわらず、それはそのコンストラクタまたはデストラクタをインスタンス化する必要はありませんので。したがって、クラスAについて何も知る必要はありません。

ソースファイルには、Aについて知る必要のある場所があります。 (また、foo/foo2が呼び出される場所でも)。 Bのコンストラクタとデストラクタは暗黙的にintrusive_ptrを呼び出します。Aの定義は利用可能でなければなりません。

//File: B.cpp 
#include "B.h" 
#include "A.h" //Include header where A is defined. 

B::B() { } 
B::~B() { } 

//Other member functions... 

これがあなたのケースで役立つかどうかは分かりませんが、それについて考えることはありません。 :)

+0

さて、私は最終的にそれを解決することができました。あなたの答えは正しい道に私を置きました。私は通常あなたが暴露したのと同じことをします。問題は、エラーに関する誤った情報や誤解を与えていたこのダムのリンゴコンパイラです。私はプロジェクトからすべてのファイルを抽出し、それらを1つずつ追加していましたが、問題はタイプが完了していないことでした。 – Notbad

3

私は次のようにintrusive_ptr_add_refintrusive_ptr_releaseのために、この使用してテンプレート関数を解くことができると思う:

namespace boost { 
    template<class T> void intrusive_ptr_add_ref(T* p) { ++(p->references) } 
    template<class T>void intrusive_ptr_release(T* p) { 
    if (--(p->references) == 0) 
     delete p 
    } 
}; 

あなたはまた、これらの宣言を使用して

template class<T> friend void ::boost::intrusive_ptr_add_ref(T*); 
template class<T> friend void ::boost::intrusive_ptr_release(T*); 

ようCRefCountedでfriend宣言を適応させる必要があります前方宣言されたクラスのintrusive_ptr

class A; 
class B { 
    ::boost::intrusive_ptr<A> _myPtr; 
}; 
class A : public CRefCounted { 
}; 
のように使用することができます

このソリューションは、あなたがCRefCountedのすべてのサブクラスのためadd_ref/release関数のペアを定義すること、(...理論的には)という欠点があるが、私は、コンパイラはとにかくインライン化を使用することを選択するだろうと思いますので、これは可能無視される。

+0

私はこのソリューションを投稿する前に試しましたが、問題を解決しませんでした。明らかに、コンパイラが不正をしていたからです。努力をいただきありがとうございます。 – Notbad

関連する問題