4

クラスCがクラスAからその仮想関数を継承し、クラスD(クラスCのネストされたクラス)がクラスB(クラスAのネストされたクラス)からそのデータフィールドを継承するようにしたかったのですが、これが私が持っているものです。

file1.h

class A{
 public:
     virtual void foo()=0;
     class B{
       public:
         int data;
     };
};

file2.h

class C : public A{
 public:
     class D : public A::B{

     };    
};

file2.cpp

void C::foo(){//code}
C::D::D():data(0){//Bad initialization list, error being data is not a member of C::D even it should inherits from its base class
 data = 0; //good! compiler can see data is a member of A::B,and C::D inherits from it
}

私は2つの質問を受けました。最初の質問は、この種の継承を実現するために私が正しい方法で行っていることです。第二に、私がコメントしたように、なぜコンパイラは手動初期化プロセスでA :: Bからのデータを見ることができますが、初期化リストにはありませんか?それらは同じスコープにあるべきではありませんか?どうもありがとうございます

Edit1

したがって、クラスC :: D(foo)がA :: B(foo)を直接継承しないが、CはAを継承する場合、CはAと、その内部クラスAを含むすべてのパブリックフィールドを継承するため、私の認識では:: B(foo)、D(foo)はA :: B(foo)とまったく同じ名前で、このようにCの内部クラスです。つまり、両方の内部クラスにfooを使用します。

class A{
 public:
     class foo{
       public:
         int data;
     };
};

class C : public A{
 public:
     class foo{

     };    
};

C :: fooを直接呼び出すと、コンパイラが混乱しますか?スコープにその名前のコンストラクターが2つあるので?または、「最も近い」ものを呼び出すことを選択します。たとえば、C:foo?継承チェーンを登る代わりに?どうもありがとうございます

4

4 に答える 4

4
  1. はい、あなたのアプローチは、この種の継承を実現する正しい方法です。

  2. 初期化子リストは、コンストラクターに渡される引数を制御するためにあります。B のコンストラクターに引数を渡すことはできますが、B のメンバーを直接初期化することはできません (コンストラクターの仕事です)。基本クラスまたはメンバーにコンストラクターが指定されていない場合は、既定のコンストラクターが使用されます。あなたの場合、コンストラクターを B に追加して、目的を達成します。

    class A {
    public:
        class B{
        public:
            B(int i) : data(i) {}
            int data;
        };
    }; 
    
    class C : public A {
        class D : public A::B {
        };
    };
    
    C::D::D() :B(0) { }
    
于 2012-09-17T15:50:37.780 に答える
3

構文的には正しい( *1)。もちろん、初期化リストとは別に。初期化リストでは、現在のクラスのメンバーのみを初期化できます (基本クラスのメンバーではありません)。それはネスティングとは何の関係もありません。

class X
{
public: 
   int x;
};
class Y : X
{
   Y() : x(0) {} //still illegal
};

私が構文上の POV と言ったのは、それは奇妙なことだからです...実際に望むものを達成するためのよりクリーンな方法があると確信しています。

于 2012-09-17T15:49:19.920 に答える
1

ネストされたクラスから継承するための構文は正しいです。

初期化子リストは、そのクラスのメンバーを初期化するためのものです。基本クラスのメンバーは、基本クラスのコンストラクターで初期化する必要があります。

于 2012-09-17T15:50:24.850 に答える