模板类有两种类型,继承和前向声明

时间:2013-01-15 11:59:11

标签: c++ templates inheritance

我正在解决这个问题。我认为这实际上是不可能做到的,但只是为了确定我是否想问这里是否确实存在解决方案。 请考虑以下代码。有两个模板化的类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?

3 个答案:

答案 0 :(得分:1)

C继承了D类型的成员,D继承了C类型的成员。所以,不,这是不可能的。

答案 1 :(得分:1)

没有解决这个问题的方法,因为你解释它并且不应该存在。正如你现在所拥有的那样:

class C : public A<C, D>

表示C将继承D类型的数据成员。反过来:

class D : public B<C, D>

表示D将继承C类型的数据成员。

如果CD,其中C有一个D ...你有一个很好的无限递归,这意味着在这种情况下任何CD对象的大小都是无限的。

所以,除非你使用指针(你可以在插入适当的空指针的任何点剪切无限链)或引用(你可以引用以前使用的对象),你不能也不应该有这种类。

答案 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; }
};