12

ソフトウェアでクラスの前方宣言を使用したいので、typedef
を使用して、クラスの完全宣言内で使用できます。

このような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;
};

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

ありがとう。

編集:私が言及していた議論を見つけました:ここに

4

2 に答える 2

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'

したがって、警告をエラーとして扱っている場合は問題にならないはずです。

于 2009-08-10T01:49:45.203 に答える
5

C++ 標準から:

5.3.5/5:

「削除されるオブジェクトの削除時点で不完全なクラス型があり、完全なクラスに重要なデストラクタまたは割り当て解除関数がある場合、動作は未定義です。」

于 2009-08-10T01:10:31.770 に答える