Наследование от класса шаблона в 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(); }