0

My questions are related to the following structure : enter image description here

The abstract levels are just here to provide the member function for the "real" classes (D1 and D2). As it needs to be highly optimized, there is no virtuality (the destructors of the abstract levels are protected). Is the part with B0-C1-C2-D1 perfectly ok in the following cases :

  1. B0, C1 and C2 have members function with different names ?

  2. C1 and C2 have a function with the same name (for example myFunction) ?

  3. C1 and C2 and D1 have a function with the same name (for example myFunction) ?

  4. B0 and C2 have a function with the same name but not C1 (for example myFunction) ?

In each case what version of the function will be called by D1 ?

EDIT : a quick piece of code to illustrate that :

template<class CRTP> class A0
{
    public:
        void myfunction1();
    protected:
        ~A0();
        double mymember;
};

template<class CRTP> class B0 : public A0<CRTP>
{
    public:
        void myfunction2();
    protected:
        ~B0();
};

template<class CRTP> class C1 : public B0<CRTP>
{
    public:
        void myfunction3();
    protected:
        ~C1();
};

template<class CRTP> class C2 : public B0<CRTP>
{
    public:
        void myfunction4();
    protected:
        ~C2();
};

class D1 : public C1<D1>, public C2<D1>
{
    public:
        void myfunction5();
};
4

2 に答える 2

0

クラス(と)は異なりますが、クラスA0に2回参加しても大丈夫でない限り、大丈夫とは言えません。あなたが何らかの専門化をしているのでない限り、これはおそらくあなたが望むものではありません。B0B0<C1>B0<C2>

これに対する可能な解決策は、多重継承を削除する次のようなものです。

template<class CRTP, class Base = B0<CRTP> > class C1 : public Base
{
    public:
        void myfunction3();
    protected:
        ~C1();
};

template<class CRTP, class Base = B0<CRTP> > class C2 : public Base
{
    public:
        void myfunction4();
    protected:
        ~C2();
};

class D1 : public C2<D1,C1<D1>>
{
    public:
        void myfunction5();
};

では、そのダイアモンドをそこに入れたい場合、複数の基本クラスインスタンスなしでそれを行うことができますか?
いいえ、 a)
基本クラスが異なり、
b)C ++の仮想継承は、vtableを持つクラスでのみ機能するためです。

于 2012-08-27T18:50:36.560 に答える
0

「PerfectlyOk」はある程度主観的ですが、すべての状況は言語内で明確に定義されています。

ダイヤモンドの継承に関する問題が発生する可能性がありますD1必要に応じて、仮想継承を使用してC1、共通ベースを使用C2したり、共通ベースから継承したりできます。それは常に適切であるとは限らず、私たちが推測するのは難しいです。

1)

それらは異なるメソッドを持つ異なるクラスであり、競合はありません。

2)

C1またはC2内に問題はありませんが、問題はD1あります。

3)

で定義する必要がありますD1。継承されmyFunctionた呼び出しは、外部からシャドウされます(アクセスできなくなります)。次のように、D1内から呼び出すことができます。

struct D1 {
  void myFunction() {
    C1::myFunction();
    C2::myFunction();
  }
}

CRTPを使用すると、これを行うのは面倒になります。クラス定義でtypedefを使用して、正気を保つことをお勧めします。

4)

C1B0それを与えるどんな機能も持つでしょう。それらにアクセスできない場合、それらを参照するとコンパイラエラーが発生します。

正直なところ、このデザインには反対することをお勧めします。すべてを小さな具体的なオブジェクトに分割し、それらを構成します。これを維持することはプロジェクトではなく、キャリアになります。

于 2012-08-27T18:11:05.693 に答える