2

私はこの問題に頭を悩ませています。実際には不可能だと思いますが、念のためここで実際に解決策があるかどうかをお聞きしたいと思います。次のコードを検討してください。2つのテンプレートクラスAとB、および2つの非テンプレートクラスCとDがあり、それぞれAとBから派生しています。

// definition of class A
template <class DerivedA, class DerivedB> class A {
private:
    DerivedB data;
public:
    A(const DerivedB& data) : data(data) {}
    virtual ~A() {}
    DerivedB get() const { return data; }
};

// definition of class B
template <class DerivedA, class DerivedB> class B {
private:
    DerivedA data;
public:
    B(const DerivedA& data) : data(data) {}
    virtual ~B() {}
    DerivedA get() const { return data; }
};

// forward declaration of D
class D;

// definition of class C, derives from A<C, D>
class C : public A<C, D> {
private:
    int extraInfo;
public:
    C(const D& d) : A(d) {}
    virtual ~C() {}
    int getExtraInfo() const { return extraInfo; }
};

// definition of class D, derives from B<C, D>
class D : public B<C, D> {
private:
    int extraInfo;
public:
    D(const C& c) : B(c) {}
    virtual ~D() {}
    int getExtraInfo() const { return extraInfo; }
};

ここでの問題は、クラスDは前方宣言されているだけなので、クラスCを定義できないことです。したがって、テンプレートAが書き出されると、プライベートメンバーのタイプがわかりません。ポインタを操作できないことに注意してください。いくつかの既知の機能が必要です。クラスCとDを持つようにコンパイルすることは可能ですか?

4

3 に答える 3

1

Cタイプのメンバーを継承し、タイプのメンバーをD継承DCます。だから、いや、それは不可能です。

于 2013-01-15T12:05:35.160 に答える
1

あなたがそれを説明するので、この問題を回避する方法はありません、そして、あるべきではありません。あなたが今それを持っているように:

class C : public A<C, D>

Cタイプのデータメンバーを継承することを意味しますD。順番に:

class D : public B<C, D>

Dタイプのデータメンバーを継承することを意味しますC

CがありD、がありC、が...である場合D、無限再帰があります。つまり、この場合、任意のオブジェクトCまたはDオブジェクトのサイズは無限になります。

したがって、ポインター(適切なnullポインターを挿入することで、いつでも無限チェーンを切断できます)または参照(以前に使用したオブジェクトを参照できます)を使用しない限り、この種のクラスを使用することはできません。

于 2013-01-15T12:24:35.320 に答える
0

これを回避するには、CとDに、必要な機能(ゲッターを含む)を備えた純粋な仮想クラスを実装させ、そのクラスをテンプレート引数として渡すようにします。次に、AとBで実際にポインタを使用しますが、すべての機能を保持します。

このようなもの(あなた自身の適応をしてください)

// definition of class A
template <class DerivedA, class DerivedB> class A {
private:
    const DerivedB& _data;
public:
    A(const DerivedB& data) : _data(data) {}
    virtual ~A() {}
    DerivedB& get() const { return data; }
};

// definition of class B
template <class DerivedA, class DerivedB> class B {
private:
    DerivedA data;
public:
    B(const DerivedA& data) : data(data) {}
    virtual ~B() {}
    DerivedA get() const { return data; }
};

class TheInterface {
public:
    virtual int getExtraInfo() const = 0;
virtual ~TheInterface() = 0;
};

// definition of class C, derives from A<C, D>
class C : public TheInterface, public A<C, TheInterface> {
private:
    int extraInfo;
public:
    C(const TheInterface& d) : A(d) {}
    virtual ~C() {}
    int getExtraInfo() const { return extraInfo; }
};

// definition of class D, derives from B<C, D>
class D : public TheInterface, public B<C, D> {
private:
    int extraInfo;
public:
    D(const C& c) : B(c) {}
    virtual ~D() {}
    int getExtraInfo() const { return extraInfo; }
};
于 2013-01-15T12:16:02.637 に答える