6

cpp の「final」の実装コードを理解しようとしていました。

以下はコードです:

/* A program with compilation error to demonstrate that Final class cannot
   be inherited */

class Final;  // The class to be made final

class MakeFinal // used to make the Final class final
{
private:
    MakeFinal() { cout << "MakFinal constructor" << endl; }
friend class Final;
};

class Final : virtual MakeFinal
{
public:
    Final() { cout << "Final constructor" << endl; }
};

class Derived : public Final // Compiler error
{
public:
    Derived() { cout << "Derived constructor" << endl; }
};

int main(int argc, char *argv[])
{
    Derived d;
    return 0;
}

出力: コンパイラ エラー

In constructor 'Derived::Derived()':
error: 'MakeFinal::MakeFinal()' is private

これでは MakeFinal クラスを仮想的に継承するロジックが理解できませんでした。単純にそれ (makeFinal クラス) を public として継承することもできますが、その場合でも、それ以上継承することはできません (Makefile のコンストラクターはプライベートであり、そのフレンドである Final クラスのみがアクセスできるため)。

ポインターはありますか??

4

1 に答える 1

11

それはうまくいきません。非仮想基底クラスは、それらから直接派生したクラスによって常に初期化されます。つまり、シナリオが次のような場合です。

class Final : public MakeFinal
{
public:
  Final() {}
};

class Derived : public Final
{};

次に、Derivedのみの ctor が初期化しますFinal。これは問題ありません (Finalパブリック ctor があります)。Finalの ctor は次に を初期化しますが、 は友人であるMakeFinalため、これも可能です。Final

ただし、仮想基本クラスの場合、ルールは異なります。すべての仮想基本クラスは、最も派生したオブジェクトの ctor によって初期化されます。つまり、 のインスタンスを作成するとき、を初期化するFinalのはFinalの ctorMakeFinalです。ただし、 のインスタンスを作成しようとする場合、を初期化するのは の ctor でDerivedなければなりません。そして、それはの私立役者のため、不可能です。DerivedMakeFinalMakeFinal

finalまた、C++11でクラス (および仮想関数)のキーワードが導入されたことにも注意してください。

于 2013-06-19T06:52:05.680 に答える