Хелпикс

Главная

Контакты

Случайная статья





Работа № 6. Программирование шаблона классов



Задание к работе

Общая постановка. Программа должна содержать:

· базовый класс Х, включающий два элемента х1, х2 типа int,

· конструктор с параметрами для создания объектов в динамической области памяти,

· деструктор,

· виртуальные методы просмотра текущего состояния и переустановки объектов базового класса в новое состояние.

· производный класс У, включающий один элемент у типа int,

· конструктор с параметрами и списком инициализаторов, передающий данные конструктору базового класса,

· переопределенные методы просмотра текущего состояния объектов и их переустановки в новое состояние.

 

Варианты заданий

Создать в производном классе метод Run, определяющий:

1. Сумму компонент классов

2. Произведение компонент классов

3. Сумму квадратов компонент классов

4. Значение х1+х2 – у

5. Значение (х1+х2)/у

6. Значение (х1+х2)*у

7. Значение х1*у+х2

8. Значение х1+х2*у

9. Произведение квадратов компонент класса

10. Значение х1*х2+у

11. Значение х1*х2/у

12. Значение х1*х2-у

13. Значение (x1-x2)*y

14. Значение (x1-x2)/y

 

Контрольные вопросы

1. Что такое наследование, одиночное наследование, множественное наследование?

2. Какие объекты базового класса наследуются в производном, а какие нет?

3. На примере своей программы поясните механизм позднего связывания.

4. В каком случае С++ проигнорирует механизм виртуальных функций?


 

 

Работа № 6. Программирование шаблона классов

 

Теоретические сведения

Задание к работе

Варианты заданий

Контрольные вопросы

 

Цель работы – изучить приемы создания и использования шаблонов классов.

 

Теоретические сведения

Достаточно часто встречаются классы, объекты которых должны содержать элементы данных произвольного типа (в том смысле, что их тип определяется отдельно для каждого конкретного объекта). В качестве примера можно привести любую структуру данных (массив указателей, массив, список, дерево). Для этого в С++ предлагаются средства, позволяющие определить некоторое множество идентичных классов с параметризованным типом внутренних элементов. Они представляют собой особого вида заготовку класса, в которой в виде параметра задан тип (класс) входящих в него внутренних элементов данных. При создании конкретного объекта необходимо дополнительно указать и конкретный тип внутренних элементов в качестве фактического параметра. Создание объекта сопровождается созданием соответствующего конкретного класса для типа, заданного в виде параметра. Принятый в С++ способ определения множества классов с параметризованным внутренним типом данных (иначе, макроопределение) называется шаблоном (template).


Синтаксис шаблона рассмотрим на примере шаблона класса векторов, содержащих динамический массив указателей на переменные заданного типа.

// < class T> - параметр шаблона - класс " T", внутренний тип данных
// vector - имя группы шаблонных классов
template < class T> class vector
{
int tsize; // Общее количество элементов
int csize; // Текущее количество элементов
T **obj; // Массив указателей на парам. объекты типа " T"
public:
T *operator[](int); // оператор [int] возвращает указатель на
// параметризованный объект класса " T"
void insert(T*); // включение указателя на объект типа " T"
int index(T*);
};


Данный шаблон может использоваться для порождения объектов-векторов, каждый из которых хранит объекты определенного типа. Имя класса при этом составляется из имени шаблона " vector " и имени типа данных (класса), который подставляется вместо параметра " Т ":

vector< int> a;
vector< double> b;
extern class time;
vector< time> c;


Заметим, что транслятором при определении каждого вектора с новым типом объектов генерируется описание нового класса по заданному шаблону (естественно, неявно в процессе трансляции). Например, для типа int транслятор получит:

class vector< int>
{
int tsize;
int csize;
int **obj;
public:
int *operator[](int);
void insert(int*);
int index(int*);
};


Далее следует очевидное утверждение, что функции- методы шаблона также должны быть параметризированы, то есть генерироваться для каждого нового типа данных. Действительно, это так: функции-методы шаблона классов в свою очередь также являются шаблонными функциями с тем же самым параметром. То же самое касается переопределяемых операторов:

// параметр шаблона - класс " T", внутренний тип данных
// имя функции-элемента или оператора - параметризировано
//
template < class T> T* vector< T>:: operator[](int n)
{
if (n > =tsize) return(NULL);
return (obj[n]);
}
template < class T> int vector< T>:: index(T *pobj)
{
int n;
for (n=0; n< tsize; n++)
if (pobj == obj[n]) return(n);
return(-1);
}


Заметим, что транслятором при определении каждого вектора с новым типом объектов генерируется набор методов- функций по заданным шаблонам (естественно, неявно в процессе трансляции). При этом сами шаблонные функции должны размещаться в том же заголовочном файле, где размещается определение шаблона самого класса. Для типа int сгенерированные транслятором функции-методы будут выглядеть так:

int* vector< int>:: operator[](int n)
{
if (n > =tsize) return(NULL);
return (obj[n]);
}
int vector< int>:: index(int *pobj)
{
int n;
for (n=0; n< tsize; n++)
if (pobj == obj[n]) return(n);
return(-1);
}

 



  

© helpiks.su При использовании или копировании материалов прямая ссылка на сайт обязательна.