Архив метки: шаблон

C++. Наследование шаблонных классов. Добавление нового типа в унаследованных классах


Наследование шаблонных классов. Добавление нового типа в унаследованных классах

Перед изучением данной темы рекомендуется ознакомиться со следующей темой:

Содержание


Поиск на других ресурсах:

1. Общие сведения о наследовании шаблонов классов

Шаблон класса, использующий некоторый обобщенный тип T, может быть унаследован другим классом. В наиболее общем случае такое наследование выглядит следующим образом
template <class T>
class BaseClass
{
  // ...
};

template <class T>
class DerivedClass : public BaseClass<T>
{
  // ...
};
где
  • BaseClass, DerivedClass – соответственно базовый и унаследованный шаблоны классов, оперирующих обобщенным типом T.
Но бывают случаи, когда в производный класс необходимо ввести дополнительный (другой) тип. Таким типом может быть тип, близкий к типу базового класса. Это, например, может быть случай, когда два типа являются классами из одной иерархии.
В таком случае код шаблонов базового и производного классов может выглядеть следующим образом:
template <class T>
class BaseClass
{
  // ...
};

template <class T1, class T2>
class DerivedClass : public BaseClass<T1>
{
  // ...
};
здесь
  • BaseClass – базовый класс в иерархии шаблонных классов использующий обобщенный тип T;
  • DerivedClass – унаследованный класс. Этот класс использует два обобщенных типа T1, T2.

 

2. Пример. Расширение типа A<TA>, B<TA, TB>, C<TA, TB, TC>
В примере, с целью демонстрации, используется добавление новых типов для классов A<TA>, B<TB>, C<TC> образующих иерархию наследования.
#include <iostream>
using namespace std;

template <class TA>
class A
{
protected:
  TA value;

public:
  A(TA value) : value(value) { }

  void Show()
  {
    cout << "A::value = " << value << endl;
  }

  TA Get() const { return value; }
};

template <class TA, class TB>
class B : public A<TA>
{
private:
  TB value;

public:
  B(TA valueA, TB valueB) :
    A<TA>(valueA), value(valueB) { }

  void Show()
  {
    A<TA>::Show();
    cout << "B::value = " << value << endl;
  }

  TA GetA() const { return A<TA>::value; }
  TB GetB() const { return value; }
};

template <class TA, class TB, class TC>
class C : public B<TA, TB>
{
private:
  TC value;

public:
  // Конструктор
  C(TA valueA, TB valueB, TC valueC) :
  B<TA, TB>(valueA, valueB), value(valueC) { }

  void Show()
  {
    B<TA, TB>::Show();
    cout << "C::value = " << value << endl;
  }

  TA GetA() const { return A<TA>::value; }
  TB GetB() const { return B<TA, TB>::value; }
  TC GetC() const { return value; }
};

int main()
{
  B<int, double> objB(10, 5.5);
  objB.Show();
  C<int, float, double> objC(20, 2.5f, 7.3);
  objC.Show();
}

 


Связанные темы

 


 

Java. Лямбда-выражения для обобщенных функциональных интерфейсов. Примеры




Читать далее Java. Лямбда-выражения для обобщенных функциональных интерфейсов. Примеры

C++. Примеры реализации шаблонных функций и перегруженных шаблонных функций. Обработка одиночных элементов. Обработка массивов




Читать далее C++. Примеры реализации шаблонных функций и перегруженных шаблонных функций. Обработка одиночных элементов. Обработка массивов