1

クラスが仮想および非仮想ベースとして使用されているのを見たことがありません (つまり、一部のクラスが先祖になることを意図している場合、通常、継承のタイプ (仮想または非仮想) について事前にわかっています)。

したがって、C++には、基本クラスリストで「仮想」継承を特殊化するためのエラーが発生しやすい自由があると思います。基本クラス自体を「仮想」として指定する方が良いはずです

それとも私が間違っているのでしょうか?

いいえの場合、そのような「仮想」クラスの偶発的な非仮想継承を防ぐためのテクニックを誰かが説明できますか?

それとも、今後の C++ 標準にいくつかの展望がありますか?

(重複していたらごめんなさい)


いくつかの例

1) 一部の参照カウントベースのスマートポインターが指すことができるすべてのクラスのベースとしての ReferenceCounted クラス。この基本インスタンス (および参照カウンター) の重複を防ぐ必要があります。最適化を除いて、このクラスを非仮想ベースとして使用する理由はありません。

2) インターフェースの階層と対応する実装の階層 (この場合、インターフェースの階層は「仮想」でなければなりません)

// インターフェイス:

構造体 BaseIface{
  void 仮想関数 () = 0;
};

struct DerivedIface: public virtual BaseIface{
  void some_another_func()=0;
}


// 実装

class BaseImpl: public virtual BaseIface{
  void virtual func(){....};
}

クラス DerivedImpl: public BaseImpl、public virtual DerivedIface{
  void some_another_func(){...};
}

多くの場合、非仮想継承は概念的な必要性ではなく、仮想継承のオーバーヘッドを削減するためだけに使用されていると思います (時には static_cast<> を駆動する機能のために:)

Javaはインターフェイスに仮想(c ++に関して)継承のみを使用したことに注意してください。この言語には「非仮想」がないという不満はありません(本質的にC ++よりも表現力の低い言語ですが、この「機能」はメインではありません障害 :)。

4

1 に答える 1

1

基本クラスでこれを行う方法はあまりありません (また、実際にそうしたくない場合もあります)。仮想継承と非仮想継承の両方に基本クラスを使用することは完全に合理的です。

あなたが本当に望むは、現在は中間クラスで指定する必要がある最も派生したクラスで仮想継承を指定することです。残念ながら、それを回避する方法はあまりありません。クラスがそれぞれ共通のベースを持つ2つ(またはそれ以上)の他のクラスから派生する場合、仮想継承が(主に)必要になりますが、仮想継承は、これら2つの他のクラスがどのように制御されるかを実際に制御しますクラスはコンパイルされているため、最も派生したクラスで(のみ)指定した場合、export仮想を指定する最も派生したクラスに基づいて、それらの中間クラスに戻って再コンパイルする必要がある場合があります。継承 (どちらかまたは両方の方法で使用される可能性があるため、両方の方法でコンパイルされた中間クラスを格納する方法があります)。

于 2010-08-10T15:03:59.750 に答える