4

別の から派生したクラスを開発していますが、次のコードで立ち往生しています。

template <class A, class B, class C>
class BaseClass
{
public:
    BaseClass(){}
    virtual void amethod( A* aPtr=0)
    {
        mAPtr=aPtr;
    }
    virtual void init()=0;
protected:
    A * mAPtr;
    B* mBPtr;
    C * mCPtr;
};
template <class A,class B,class C>
class ChildClass: public BaseClass<A,B,C>
{
public:
    ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0):mAPtr(aAptr)
      ,mBPtr(aBPtr)
      ,mCPtr(aCPtr)
    {}

};
int main()
{

    return 0;
}

コンパイラーは、子クラスには親フィールドがないことを示しています。

コンパイラ出力:

 In constructor 'ChildClass<A, B, C>::ChildClass(A*, B*, C*)'
 In constructor 'ChildClass<A, B, C>::ChildClass(A*, B*, C*)'
error: class 'ChildClass<A, B, C>' does not have any field named 'mAPtr'
error: class 'ChildClass<A, B, C>' does not have any field named 'mBPtr'
error: class 'ChildClass<A, B, C>' does not have any field named 'mCPtr'

私はグーグルで検索していますが、答えが見つかりません:事前にThx

4

4 に答える 4

6

派生クラスのコンストラクターで、基本メンバー変数を直接コンストラクターで初期化することはできません。

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0)
    : mAPtr(aAptr)  // <-- Member belongs to parent
    , mBPtr(aBPtr) // <-- Member belongs to parent
    , mCPtr(aCPtr) // <-- Member belongs to parent
{
}

基本コンストラクターでそれらをデフォルトで構築し、それらを割り当てることができます(保護されているため)

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0)
{
    mAPtr = aAptr;  // <-- Member belongs to parent but you can access it
    mBPtr = aBPtr; // <-- Member belongs to parent but you can access it
    mCPtr = aCPtr; // <-- Member belongs to parent but you can access it
}

または、親クラスのコンストラクターを変更できます

BaseClass( A* aAptr, B * aBPtr0, C* aCPtr)
    : mAPtr(aAptr)
    , mBPtr(aBPtr)
    , mCPtr(aCPtr)
{
}

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0)
  : BaseClass(aAptr, aBPtr, aCPtr)
{
}

また、派生クラスで void init() メソッドを定義する必要があることを覚えておいてください

于 2013-08-27T19:27:26.797 に答える
5

派生クラスのコンストラクターの初期化リストで、基本クラスのデータ メンバーを初期化することはできません。コンストラクターの本体でそれらを割り当てることができます。

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0) {
  mAPtr = aAptr;
  mBPtr = aBPtr;
  mCPtr = aCPtr;
}

ただし、基本クラスの設計はお粗末に見えます。その唯一のコンストラクターは 3 つのデータ メンバーをまったく初期化せず ( に対してもNULL)、ランダムなガベージを含むことになります。おそらくBaseClass、データ メンバーを初期化する 3 つのパラメーターのコンストラクターを持つことは理にかなっています。のコンストラクターはChildClass、initialzier リストを介して単純にそれを転送します。

于 2013-08-27T19:24:48.820 に答える
3

フアン、このコード:

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0)
{
    mAPtr = aAptr;  // <-- Member belongs to parent but you can access it
    mBPtr = aBPtr; // <-- Member belongs to parent but you can access it
    mCPtr = aCPtr; // <-- Member belongs to parent but you can access it
}

同じコンパイラ エラーが発生する場合は、次の方法で基本クラスを明示的に記述する必要があります。

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0)
{
    BaseClass<A,B,C>::mAPtr = aAptr;
    BaseClass<A,B,C>::mBPtr = aBPtr;
    BaseClass<A,B,C>::mCPtr = aCPtr;
}
于 2013-08-27T20:44:15.787 に答える
1

上記の anwser を使用して、少し変更しました:

ChildClass( A* aAptr =0, B * aBPtr= 0, C* aCPtr= 0)
    {
        this->mAPtr=aAptr;
        this->mBPtr=aBPtr;
        this->mCPtr=aCPtr;
    }

this ポインターがないと、コンパイラーは親からの変数を認識しません。Thx!、ちなみに、コンパイルは Gcc コンパイラー gcc バージョン 4.7.3 を使用する Linux 用でした。

于 2013-08-27T19:32:09.170 に答える