2009-08-10 32 views
12

は、私は私のソフトウェアで、クラスの宣言を前方に使用したいので、私は
のtypedefがあり、クラスフル宣言内にそれらを使用することができます。このようなC++クラスの前方宣言の欠点?

SMTH:

class myclass; 
typedef boost::shared_ptr<myclass> pmyclass; 
typedef std::list<pmyclass > myclasslist; 

class myclass : public baseclass 
{ 
private:  // private member declarations 
     __fastcall myclass(); 

public:   // public member declarations 
     __fastcall myclass(myclass *Parent) 
      : mEntry(new myclass2()) 
      { 
      this->mParent = Parent; 
      } 
     const myclass *mParent; 
     myclasslist mChildren; 
     boost::scoped_ptr<myclass2> mEntry; 
}; 

ので、私の質問です:この方法で任意の欠点が がありますか?私はフォワード宣言でデストラクタの問題に関する議論を思い出しましたが、私はそこからすべてを得ることはできませんでした。
またはこのような何かを実装するための他のオプションはありますか?

ありがとうございました。

EDIT:

5.3.5/5:

「が削除されているオブジェクトがある場合は、不完全なクラス型C++標準からhere

答えて

5

:私は、私が言及した議論を見つけ 削除、完全なクラスの時点で、動作は未定義で、非自明なデストラクタまたは 解除機能を持っています。」

+0

が、私は前にそれを読んでいたし、ここで私の質問は: それが適切な宣言の後に定義されている場合は問題はないはず、右? – Andrew

+1

はい、まあそれは私がそれを読む方法です。私たちのコンパイラが標準に準拠していることを祈っています: –

22

主な欠点は、すべてです。フォワード宣言は、コンパイル時間を節約し、オブジェクト間の循環依存性を持たせる妥協案です。しかし、コストは参照としてのみ型を使用でき、それらの参照では何もできません。つまり、継承も、値渡しも、クラス内のネストされた型やtypedefも使用しません。これらはすべて大きな欠点です。

あなたが話している特定の破壊の問題は、あなただけのフォワード型を宣言し、モジュールだけでそれを削除してしまった場合、動作は未定義であると、エラーがスローされませんです。例えば

class A; 

struct C 
{ 
    F(A* a) 
    { 
     delete a; // OUCH! 
    } 
} 

のMicrosoft C++ 2008は、任意のデストラクタを呼び出すと、次の警告をスローしません。だから、あなたがあれば問題になることはありませんこれは、警戒する必要が

warning C4150: deletion of pointer to incomplete type 'A'; no destructor called 
      : see declaration of 'A' 

を警告をエラーとして扱います。愚かさのため申し訳ありませんうまく

+5

1時間に30分のコンパイル時間を節約できますが、前方に宣言された頭痛で時間がかかる場合は、CPUを購入してくださいより多くのコアを使用し、並列コンパイルを可能にします。少なくとも、より良いフレームレートで後でSkyrimをプレイすることができます。 – Eloff