从 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
Inheriting from a template class in c++
提问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 area
aT getArea()
和一个void setArea(T)
成员函数。
I can create an Area
object of a specific type by typing Area<int>
.
我可以Area
通过键入来创建特定类型的对象Area<int>
。
Now I have a class Rectangle
that inherits the Area
class. Since Rectangle
itself is not a template, I cannot type Rectangle<int>
.
现在我有一个Rectangle
继承Area
该类的类。由于Rectangle
它本身不是模板,我无法输入Rectangle<int>
.
How do I specialize the inherited Area
type for Rectangle
objects?
如何专门化对象的继承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, Area
is 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 Area
is not a class, you cannot derive the class Rectangle
from 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 Rectangle
from 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 Rectangle
a template as well. If you write
你可以做的是制作Rectangle
一个模板。如果你写
template<typename T> class Rectangle:
public Area<T>
{
// ...
};
You have a template Rectangle
from 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 Rectangle
so that you can pass all sorts of Rectangle
to the same function (which itself doesn't need to know the Area type). Since the Rectangle<T>
classes generated by instantiating the template Rectangle
are 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 Rectangle
is derived from a generic Area
you can do the same trick with Area
too:
如果您的泛型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 Rectangle
a 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
Rectangle
will 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();
}