2

我正在解决这个问题。我认为这实际上是不可能的,但只是为了确定我想在这里问一下是否真的有解决方案。考虑以下代码。有 2 个模板类 A 和 B 以及两个非模板类 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; }
};

这里的问题是不能定义类 C,因为类 D 只是前向声明的。因此,当模板 A 被写出时,它不知道它的私有成员的类型是什么。请注意,我不能使用指针,我需要一些已知的功能。是否可以以任何方式编译以使我拥有我的 C 类和 D 类?

4

3 回答 3

1

C继承 type 的成员DD继承 type 的成员C。所以,不,这是不可能的。

于 2013-01-15T12:05:35.160 回答
1

正如您所解释的那样,没有办法解决这个问题,也不应该有。正如你现在拥有的那样:

class C : public A<C, D>

意味着C将继承类型的数据成员D。反过来:

class D : public B<C, D>

意味着D将继承类型的数据成员C

If Chas a D, which has a C, which has a D...你有一个很好的无限递归,这意味着在这种情况下任何CD对象的大小将是无限的。

因此,除非您使用指针(您可以在任何点插入适当的空指针来切断无限链)或引用(您可以引用以前使用的对象),否则您不能也不应该拥有这种类。

于 2013-01-15T12:24:35.320 回答
0

你可以通过让 C 和 D 实现一个纯虚拟类,以及你需要的功能(包括 getter),并让它们将该类作为模板参数传递,从而摆脱这种情况。然后,您实际上在 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 回答