Наследование от класса шаблона в C++
Допустим у нас есть шаблон класса Area
, который имеет переменную-член T area
, a T getArea()
и void setArea(T)
функции-члены.
я могу создать Area
объект определенного типа, набрав Area<int>
.
теперь у меня есть класс Rectangle
унаследовала Area
класса. Так как Rectangle
сам по себе не шаблон, я не могу набрать Rectangle<int>
.
как я специализируюсь на наследство Area
тип Rectangle
объекты?
редактировать: Извините, я забыл уточнить-мои вопросы заключается в том, можно ли наследовать область, не специализируя ее, поэтому она не наследуется как область ints, а как прямоугольник области может специализировать типы.
6 ответов:
для понимания шаблонов, это огромное преимущество, чтобы получить в терминологии, потому что как вы говорите о них, определяет способ думать о них.
в частности,
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 };
вы просто пытаетесь вывести из
Area<int>
? В этом случае вы делаете следующее:class Rectangle : public Area<int> { // ... };
EDIT: после уточнения, кажется, вы на самом деле пытаетесь сделать
Rectangle
шаблон, а также, в этом случае должно работать следующее:template <typename T> class Rectangle : public Area<T> { // ... };
Rectangle
должен быть шаблон, иначе это только один тип. Он не может быть не-шаблоном, пока его основа магически есть. (Его базой может быть шаблон экземпляров, хотя вы, кажется, хотите сохранить функциональность базы как шаблон.)
сделайте прямоугольник шаблоном и передайте имя типа в область:
template <typename T> class Rectangle : public Area<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(); }