web-dev-qa-db-ja.com

仮想関数の継承

メソッドの仮想プロパティを継承することについて混乱があります。

クラスA、クラスB、クラスC、クラスDの4つのクラスがあるとします。クラスは次のように継承されます:A-> B-> C-> D、ここでAは基本クラスです。

この時点で、私はこれについて確信しています。基本クラス(クラスA)のvirtualでクラスメソッド宣言を開始すると、派生クラスの派生クラスを含む、基本クラスから派生したすべてのクラスのメソッドが仮想になります。 (仮想であると判断されたBおよびCクラスのメソッド)。

混乱はここにあります。基本クラスAに、仮想メンバーがない場合はどうなりますか。代わりに、クラスBがメソッドを仮想であると宣言するとします。この変更により、継承チェーンに属するすべての派生クラス(CクラスとDクラス)の関数が仮想化されると思います。論理的には、CとDを表すBは、一種の「基本クラス」ですよね?それとも私は間違っていますか?

12

あなたは正しいです。

この場合の最善の解決策は、次のことを試すことだと思います。

#include <iostream>

using namespace std;

class A {
   public:
      void print(){ cout << "print A" << endl; };
};

class B: public A {
    public:
       virtual void print(){ cout << "print B" << endl; };
};

class C: public B {
     public:
        void print(){ cout << "print C" << endl; };
};

int main()
{
   A *a = new C();
   B *b = new C();

   a->print(); // will print 'print A'
   b->print(); // will print 'print C'

   return 1;
}
17
kist

あなたは完全に正しいです。子供はその祖先が持っているものを継承します。基本クラスは、子が持つもの(新しい関数や変数など)を継承できません。仮想関数は、子クラスが仮想関数の実装を変更して基本仮想関数が呼び出されない場合に、子クラスによってオーバーライドできる関数です。

AはB、C、Dの基本クラスです。 BはC、Dの基本クラスであり、CもDの基本クラスです。

5
theta

もちろん、あなたはそれを行うことができます。仮想メソッドはオーバーライドするオプションであるため、クラスAまたはBで宣言する必要はありません。クラスAでそのメソッドを使用したくない場合は、クラスBで宣言するだけです。

0
user2546623