假设我们有一个模板类Area
,它有一个成员变量T area
,一个T getArea()
和一个void setArea(T)
成员函数。
我可以通过输入Area
来创建特定类型的Area<int>
对象。
现在我有一个继承Rectangle
类的类Area
。由于Rectangle
本身不是模板,因此我无法输入Rectangle<int>
。
如何为Area
对象专门化继承的Rectangle
类型?
编辑:对不起,我忘了澄清 - 我的问题是是否可以继承区域而不专门化它,因此它不会作为整数区域继承,但区域矩形可以专门化类型。
答案 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();
}