从 c + + 中的模板类继承

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

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

现在我有了一个继承 Area类的类 Rectangle。因为 Rectangle本身不是模板,所以我不能键入 Rectangle<int>

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

编辑: 对不起,我忘了澄清-我的问题是,是否有可能继承 Area 而不专门化它,所以它不是作为整型面积继承,但面积矩形可以专门化的类型。

204589 次浏览

Rectangle必须是一个模板,否则它就是 只有一种。它不能是一个非模板,而它的基础是魔术。(它的基础可能是一个模板 实例化,尽管您似乎想要维护基础的功能 作为模板。)

class Rectangle : public Area<int> {
};

你只是试图从 Area<int>得出结论吗? 在这种情况下,你可以这样做:

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

编辑: 在澄清之后,似乎您实际上也在尝试使 Rectangle成为一个模板,在这种情况下,以下内容应该可以工作:

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

使矩形成为一个模板,并将类型名传递到 Area:

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


};

为了理解模板,理解术语是非常有益的,因为您谈论它们的方式决定了思考它们的方式。

具体来说,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,从中可以获得从 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
};
#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();
}