继承自c ++中的模板类

时间:2012-01-10 20:41:25

标签: c++ templates inheritance

假设我们有一个模板类Area,它有一个成员变量T area,一个T getArea()和一个void setArea(T)成员函数。

我可以通过输入Area来创建特定类型的Area<int>对象。

现在我有一个继承Rectangle类的类Area。由于Rectangle本身不是模板,因此我无法输入Rectangle<int>

如何为Area对象专门化继承的Rectangle类型?

编辑:对不起,我忘了澄清 - 我的问题是是否可以继承区域而不专门化它,因此它不会作为整数区域继承,但区域矩形可以专门化类型。

6 个答案:

答案 0 :(得分:196)

为了理解模板,使术语直截了当是非常有利的,因为你谈论它们的方式决定了思考它们的方式。

具体来说,Area不是模板类,而是类模板。也就是说,它是一个可以从中生成类的模板。 Area<int>就是这样一个类(它的不是一个对象,但当然你可以用与从任何其他类创建对象相同的方式从该类创建一个对象)。另一个这样的课程是Area<char>。请注意,这些是完全不同的类,除了它们是从同一个类模板生成的事实之外没有任何共同之处。

由于Area不是类,因此无法从中派生类Rectangle。您只能从另一个类(或其中几个)派生一个类。由于Area<int>是一个类,因此您可以从中派生Rectangle

class Rectangle:
  public Area<int>
{
  // ...
};

由于Area<int>Area<char>是不同的类,您甚至可以同时从这两个类派生(但是当访问它们的成员时,您将不得不处理歧义):

class Rectangle:
  public Area<int>,
  public Area<char>
{
  // ...
};

但是,您必须在定义Rectangle时指定从中派生的类别。无论这些类是否是从模板生成,都是如此。同一个类的两个对象根本不能有不同的继承层次结构。

您可以做的是使Rectangle成为模板。如果你写

template<typename T> class Rectangle:
  public Area<T>
{
  // ...
};

您有一个模板Rectangle,您可以从中Rectangle<int>获取一个类Area<int>,另一个类Rectangle<char>来自Area<char>

可能您希望拥有单个类型Rectangle,以便您可以将各种Rectangle传递给同一个函数(它本身不需要知道区域类型)。由于通过实例化模板Rectangle<T>生成的Rectangle类在形式上彼此独立,因此它不起作用。但是,您可以在此处使用多重继承:

class Rectangle // not inheriting from any Area type
{
  // Area independent interface
};

template<typename T> class SpecificRectangle:
  public Rectangle,
  public Area<T>
{
  // Area dependent stuff
};

void foo(Rectangle&); // A function which works with generic rectangles

int main()
{
  SpecificRectangle<int> intrect;
  foo(intrect);

  SpecificRectangle<char> charrect;
  foo(charrect);
}

如果您的通用Rectangle来自通用Area非常重要,那么您也可以使用Area执行相同的操作:

class Area
{
  // generic Area interface
};

class Rectangle:
  public virtual Area // virtual because of "diamond inheritance"
{
  // generic rectangle interface
};

template<typename T> class SpecificArea:
  public virtual Area
{
  // specific implementation of Area for type T
};

template<typename T> class SpecificRectangle:
  public Rectangle, // maybe this should be virtual as well, in case the hierarchy is extended later
  public SpecificArea<T> // no virtual inheritance needed here
{
  // specific implementation of Rectangle for type T
};

答案 1 :(得分:15)

您是否只是想从Area<int>派生出来?在这种情况下,你这样做:

class Rectangle : public Area<int>
{
    // ...
};

编辑:在澄清之后,您似乎也在尝试将Rectangle作为模板,在这种情况下,以下情况应该有效:

template <typename T>
class Rectangle : public Area<T>
{
    // ...
};

答案 2 :(得分:8)

class Rectangle : public Area<int> {
};

答案 3 :(得分:8)

将Rectangle设为模板并将typename传递给Area:

template <typename T>
class Rectangle : public Area<T>
{

};

答案 4 :(得分:6)

Rectangle必须是模板,否则只是一种。它不可能是一个非模板,而它的基础是神奇的。 (它的基础可能是模板 instantiation ,但您似乎想要将基础功能维护为模板。)

答案 5 :(得分:0)

#include<iostream>

using namespace std;

template<class t> 
class base {
protected:
    t a;
public:
    base(t aa){
        a = aa;
        cout<<"base "<<a<<endl;
    }
};

template <class t> 
class derived: public base<t>{
    public:
        derived(t a): base<t>(a) {
        }
        //Here is the method in derived class 
    void sampleMethod() {
        cout<<"In sample Method"<<endl;
    }
};

int main() {
    derived<int> q(1);
    // calling the methods
    q.sampleMethod();
}