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,一个T getArea()和一个void setArea(T)成员函数。
I can create an Area
object of a specific type by typing Area<int>
.
我可以通过键入Area
Now I have a class Rectangle
that inherits the Area
class. Since Rectangle
itself is not a template, I cannot type Rectangle<int>
.
现在我有一个继承Area类的Rectangle类。由于Rectangle本身不是模板,因此我无法输入Rectangle
How do I specialize the inherited Area
type for Rectangle
objects?
如何为Rectangle对象专门化继承的Area类型?
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.
编辑:对不起,我忘了澄清 - 我的问题是是否可以继承区域而不专门化它,因此它不会作为整数区域继承,但区域矩形可以专门化类型。
6 个解决方案
#1
156
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 not an 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
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
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
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,你可以从中获得一个派生自Area
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生成的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执行相同的技巧:
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
};
#2
11
Are you just trying to derive from Area<int>
? In which case you do this:
你只是想从Area
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>
{
// ...
};
#3
7
class Rectangle : public Area<int> {
};
#4
5
Make Rectangle a template and pass the typename on to Area:
使Rectangle成为模板并将typename传递给Area:
template <typename T>
class Rectangle : public Area<T>
{
};
#5
4
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必须是一个模板,否则它只是一种类型。它不可能是非模板,而它的基础是神奇的。 (它的基础可能是模板实例化,但您似乎希望将基础功能保留为模板。)
#6
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();
}
#1
156
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 not an 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
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
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
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,你可以从中获得一个派生自Area
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生成的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执行相同的技巧:
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
};
#2
11
Are you just trying to derive from Area<int>
? In which case you do this:
你只是想从Area
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>
{
// ...
};
#3
7
class Rectangle : public Area<int> {
};
#4
5
Make Rectangle a template and pass the typename on to Area:
使Rectangle成为模板并将typename传递给Area:
template <typename T>
class Rectangle : public Area<T>
{
};
#5
4
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必须是一个模板,否则它只是一种类型。它不可能是非模板,而它的基础是神奇的。 (它的基础可能是模板实例化,但您似乎希望将基础功能保留为模板。)
#6
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();
}