从c++中的模板类继承

Inheriting from a template class in c++

本文关键字:继承 c++      更新时间:2023-10-16

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

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

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

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

编辑:对不起,我忘记澄清了-我的问题是,是否可以在不专门化Area的情况下继承Area,所以它不是作为int的Area继承的,而是作为Area Rectangle可以专门化的类型继承的。

对于理解模板,弄清术语是非常有利的,因为谈论它们的方式决定了思考它们的方式。

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

由于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,从中可以获得从Area<int>派生的类Rectangle<int>和从Area<char>派生的不同类Rectangle<char>

可能您想要一个类型Rectangle,这样您就可以将所有类型的Rectangle传递给同一个函数(该函数本身不需要知道Area类型)。由于通过实例化模板Rectangle生成的Rectangle<T>类在形式上是相互独立的,所以它不能以这种方式工作。然而,您可以在这里使用多重继承:

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

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

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

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

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

将矩形作为模板,并将类型名称传递给区域:

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

Rectangle必须是一个模板,否则它只是一种类型。它不能是一个非模板,而它的基础神奇地是。(它的基础可能是一个模板实例化,尽管你似乎想把基础的功能作为模板来维护。)

#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();
}