
- •Базовые принципы объектно-ориентированного программирования.
- •Базовые конструкции объектно-ориентированных программ.
- •Конструктор и деструктор. Конструктор по умолчанию.
- •Конструктор копирования.
- •Конструктор explicit.
- •Указатель this.
- •Абстрактные типы данных.
- •Операторы для динамического выделения и освобождения памяти (new и delete).
- •Перегрузка и переопределение функций.
- •Перегрузка бинарных операторов.
- •Перегрузка унарных операторов.
- •19.20.Перегрузка оператора new.Перегрузка оператора delete.
- •22.Inline-функции.
- •23.Вложенные классы
- •24.Static-компоненты данные класса
- •25.26.Static и const-компоненты функции класса
- •27.Использование new delete для реализации массивов
- •28.Организация внешнего доступа к локальным компонентам класса(friend)
- •29.Ссылки.Параметры ссылки
- •30.Ссылки.Независимые ссылки
- •31.Инициализация компонент-данных объекта. Конструктор с параметрами.
- •33.Наследование. Открытое, защищенное и закрытое.
- •34.Виртуальные функции.
- •35.Множественное наследование.
- •36.Множественное наследование и виртуальные базовые классы
- •38.Proxi-классы.
- •39.40.Пространство имен. Пространство имен как объявление. Пространство имен как директива.
- •41.Виртуальные функции
- •42.Параметризированные классы (шаблоны).
- •43.Шаблоны функций.
- •44.Передача в шаблон класса дополнительных параметров.
- •44.Совместное использование шаблонов и наследования.
- •45.Шаблоны класса и friend.
- •46.Реализация smart-указателя.
- •48.Транзакции.
44.Передача в шаблон класса дополнительных параметров.
При создании экземпляра класса из шаблона в него могут быть переданы не только типы, но и переменные и константные выражения:
#include <iostream>
using namespace std;
template <class T1,int i=0,class T2>
class cls
{ T1 a;
T2 b;
public:
cls(T1 A,T2 B) : a(A),b(B){}
~cls(){}
T1 sm() //описание шаблона функции суммирования компонент
{ // i+=3; // error member function 'int __thiscall cls<int,2>::sm(void)'
return (T1)(a+b+i); //a=b+i; return a;
}
};
int main()
{ cls <int,1,int> obj1(3,2); // в шаблоне const i инициализируется 1
cls <int,0,int> obj2(3,2,1); // error 'cls<int,0>::cls<int,0>':no overloaded
// function takes 3 parameter s
cls <int,int,int> obj13(3,2,1); // error 'cls' : invalid template argument for 'i',
// constant expression expected
cls <int,int> obj2(3,1); // error (аналогично предыдущей)
cout<<obj1.sm()<<endl;
return 0;
}
Результатом работы программы будет выведенное на экран число 6.
В этой программе инструкция template <class T1,int i=0,class T2> гово-
рит о том, что шаблон класса cls имеет три параметра, два из которых − имена
типов (Т1 и Т2), а третий (int i=0) − целочисленная константа. Значение кон-
станты i может быть изменено при описании объекта cls <int,1,int> obj1(3,2). В
этом случае инициализация константы i в инструкции template не требуется
template <class T1,int i,class T2>
44.Совместное использование шаблонов и наследования.
Шаблонные классы, как и обычные, могут использоваться повторно.
Шаблоны и наследование представляют собой механизмы повторного использования кода и могут включать полиморфизм. Шаблоны и наследования связаны между собой следующим образом:
- шаблон класса может быть порожден от обычного класса;
- шаблонный класс может быть производным от шаблонного класса;
- обычный класс может быть производным от шаблона класса.
Ниже приведен пример простой программы, демонстрирующей наследование шаблонного класса oper от шаблонного класса vect.
#include <iostream>
using namespace std;
template <class T>
class vect // класс-вектор
{protected:
T *ms; // массив-вектор
int size; // размерность массива-вектора
public:
vect(int n) : size(n) // конструктор
{ ms=new T[size];}
~vect(){delete [] ms;} // деструктор
T &operator[](const int ind) // доопределение операции []
{ if((ind>0) && (ind<size)) return ms[ind];
else return ms[0];
}
};
template <class T>
class oper : public vect<T> // класс операций над вектором
{ public:
oper(int n): vect<T>(n) {} // конструктор
~oper(){} // деструктор
void print() // функция вывода содержимого вектора
{ for(int i=0;i<size;i++)
cout<<ms[i]<<' ';
cout<<endl;
}
};
int main()
{ oper <int> v_i(4); // int-вектор
oper <double> v_d(4); // double-вектор
v_i[0]=5; v_i[1]=3; v_i[2]=2; v_i[3]=4; // инициализация int
v_d[0]=1.3; v_d[1]=5.1; v_d[2]=.5; v_d[3]=3.5; // инициализация double
cout<<"int вектор = ";
v_i.print();
cout<<"double вектор = ";
v_d.print();
return 0;
}
Как следует из примера, реализация производного класса от класса-шаблона в основном ничем не отличается от обычного наследования.