从 C++ 中的模板类继承

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8810224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:08:55  来源:igfitidea点击:

Inheriting from a template class in c++

c++templatesinheritance

提问by dtech

Let's say we have a template class Area, which has a member variable T area, a T getArea()and a void setArea(T)member functions.

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

I can create an Areaobject of a specific type by typing Area<int>.

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

Now I have a class Rectanglethat inherits the Areaclass. Since Rectangleitself is not a template, I cannot type Rectangle<int>.

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

How do I specialize the inherited Areatype for Rectangleobjects?

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

EDIT: Sorry, I forgot to clarify - my questions is whether it is possible to inherit Area without specializing it, so it is not inherited as Area of ints but as Area Rectangle can specialize the types for.

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

回答by celtschk

For understanding templates, it's of huge advantage to get the terminology straight because the way you speak about them determines the way to think about them.

为了理解模板,直接理解术语有很大的优势,因为你谈论它们的方式决定了思考它们的方式。

Specifically, Areais not a template class, but a class template. That is, it is a template from which classes can be generated. Area<int>is such a class (it's notan object, but of course you can create an object from that class in the same ways you can create objects from any other class). Another such class would be Area<char>. Note that those are completely different classes, which have nothing in common except for the fact that they were generated from the same class template.

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

Since Areais not a class, you cannot derive the class Rectanglefrom it. You only can derive a class from another class (or several of them). Since Area<int>is a class, you could, for example, derive Rectanglefrom it:

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

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

Since Area<int>and Area<char>are different classes, you can even derive from both at the same time (however when accessing members of them, you'll have to deal with ambiguities):

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

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

However you have to specify which classed to derive from when you define Rectangle. This is true no matter whether those classes are generated from a template or not. Two objects of the same class simply cannot have different inheritance hierarchies.

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

What you can do is to make Rectanglea template as well. If you write

你可以做的是制作Rectangle一个模板。如果你写

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

You have a template Rectanglefrom which you can get a class Rectangle<int>which derives from Area<int>, and a different class Rectangle<char>which derives from Area<char>.

您有一个模板Rectangle,从中可以得到一个类Rectangle<int>从派生Area<int>,和不同类Rectangle<char>从中导出Area<char>

It may be that you want to have a single type Rectangleso that you can pass all sorts of Rectangleto the same function (which itself doesn't need to know the Area type). Since the Rectangle<T>classes generated by instantiating the template Rectangleare formally independent of each other, it doesn't work that way. However you can make use of multiple inheritance here:

可能您希望拥有单一类型,Rectangle以便您可以将各种类型传递Rectangle给同一个函数(它本身不需要知道 Area 类型)。由于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);
}

If it is important that your generic Rectangleis derived from a generic Areayou can do the same trick with Areatoo:

如果您的泛型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
};

回答by Stuart Golodetz

Are you just trying to derive from Area<int>? In which case you do this:

你只是想从Area<int>? 在这种情况下,您可以这样做:

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

EDIT: Following the clarification, it seems you're actually trying to make Rectanglea template as well, in which case the following should work:

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

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

回答by pezcode

Make Rectangle a template and pass the typename on to Area:

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

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

};

回答by ldanko

class Rectangle : public Area<int> {
};

回答by Lightness Races in Orbit

Rectanglewill have to be a template, otherwise it is just one type. It cannot be a non-template whilst its base magically is. (Its base may be a template instantiation, though you seem to want to maintain the base's functionality as a template.)

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

回答by Narendra kumawat

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