Наследование от класса шаблона в C++


Допустим у нас есть шаблон класса Area, который имеет переменную-член T area, a T getArea() и void setArea(T) функции-члены.

я могу создать Area объект определенного типа, набрав Area<int>.

теперь у меня есть класс Rectangle унаследовала Area класса. Так как Rectangle сам по себе не шаблон, я не могу набрать Rectangle<int>.

как я специализируюсь на наследство Area тип Rectangle объекты?

редактировать: Извините, я забыл уточнить-мои вопросы заключается в том, можно ли наследовать область, не специализируя ее, поэтому она не наследуется как область ints, а как прямоугольник области может специализировать типы.

6 67

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>
{
    // ...
};
class Rectangle : public Area<int> {
};

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();
}