我正在解决这个问题。我认为这实际上是不可能做到的,但只是为了确定我是否想问这里是否确实存在解决方案。 请考虑以下代码。有两个模板化的类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?
答案 0 :(得分:1)
C
继承了D
类型的成员,D
继承了C
类型的成员。所以,不,这是不可能的。
答案 1 :(得分:1)
没有解决这个问题的方法,因为你解释它并且不应该存在。正如你现在所拥有的那样:
class C : public A<C, D>
表示C
将继承D
类型的数据成员。反过来:
class D : public B<C, D>
表示D
将继承C
类型的数据成员。
如果C
有D
,其中C
有一个D
...你有一个很好的无限递归,这意味着在这种情况下任何C
或D
对象的大小都是无限的。
所以,除非你使用指针(你可以在插入适当的空指针的任何点剪切无限链)或引用(你可以引用以前使用的对象),你不能也不应该有这种类。
答案 2 :(得分: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; }
};