Добавил:
Помощь с лабораторными, контрольными практическими и курсовыми работами по: - Инженерной и компьютерной графике - Прикладной механике Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2 сем 1 курс С++ / Экзамен / Lektsii_Kurakina_2_semestr.pdf
Скачиваний:
12
Добавлен:
08.08.2022
Размер:
4.82 Mб
Скачать

triangle t; rectangle s; circle c; p=&t;

p->set_dim(3,4); p->show_area(); p=&s;

p->set_dim(5,6); p->show_area(); p=&c;

p->set_dim(8); p->show_area();

}

7.5 Виртуальные базовые классы

При наследовании класса при создании объекта производного типа выполняются последовательно конструкторы всех классов прародителей, начиная с самого базового.

Деструктор в производном классе должен выполняться прежде выполнения деструктора в базовом классе. При множественном наследовании, когда базовые классы перечисляются через запятую, при создании объекта, конструкторы выполняются в порядке следования базовых классов слева направо.

При множественном наследовании базовый класс не может быть задан в производном классе более одного раза, но базовый класс может быть передан производному классу более одного раза косвенно.

class X : public Base{…};

class Y : public Base{…};

class D : public X, public Y{…};

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

class X : virtual public Base{…};

class Y : virtual public Base{…};

class D : virtual public X, public Y{…};

Класс D имеет один подобъект класса Base.

7.6 Шаблоны

Шаблоны – это одна из реализаций полиморфизма в С++.

Механизм шаблонов в языке С++ позволяет решать проблему унификации алгоритма для различных типов: нет необходимости писать различные функции для целочисленных, действительных или пользовательских типов – достаточно составить обобщенный алгоритм, не зависящий от типа данных, основывающийся только на общих свойствах. Например, алгоритм сортировки может работать как с целыми числами, так и с объектами типа «автомобиль».

Шаблон представляет собой специальное описание родовой (параметризированной) функции или родового класса, в которой информация об используемых в реализации типов данных преднамеренно остаётся незаданной.

По описанию шаблон функции похож на обычную функцию: разница в том, что некоторые элементы не определены (типы, константы) и являются параметризованными.

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

Шаблон создаётся при помощи ключевого слова template и угловых скобок <> со списком параметров, за которым следует описание класса или функции.

template <class фикт_имя1, class фикт_имя2 …>

Вместо ключевого слова class допускается использование ключевого слова typename. Шаблоны тождественны интеллектуальным макросам, которые способны сообщить компилятору о каждом случае использования шаблона новых типов данных.

7.7 Шаблоны функций

Пример: определить максимальное значение из двух аргументов max(x,y).

Способы реализации:

1.В случае целых и вещественных чисел придется написать 2 функции.

2.макрос

#define max(x,y) (((x)>(y)?(x): (y))

Преимущество — можно сравнивать данные различных типов

Недостаток — позволяет сравнивать несовместимые типы данных, т.е отсутствует механизм контроля типов данных.

3. Используя вместо макроса шаблон, можно определить заготовку для семейства связанных перегруженных функций или классов, при этом тип данных передавать как параметр.

template <class T>

T max(Tx,Ty)

{return (x>y) ? x : y;};

Здесь тип данных представляется аргументом класса T.

Т – фиктивное имя типа данных, которое программист выбирает по своему усмотрению.

Компилятор сгенерирует соответствующий код функции max() согласно действительному типу данных, используемому при вызове функции.

7.8 Пример

Пример:

#include<string.h>

#include<iostream.h> template<class T>

T max(Tx,Ty) {return(x>y)?x:y;}; int main()

{int a=5, b=30, c=15, d=0; float pi=3.14, e=2.172;

cout<<”наиб.2х целых”<<max(d,a);

d=max(a,max(b,c));

cout<<”наиб.3х целых”<<d;

cout<<”max(pi,e)=”<<max(pi,e); char m[]=”мама”,p[]=”папа”,*s; s=max(p,m);

cout<<”кто в доме хозяин?”<<s;

}

Для приведённой программы компилятор автоматически сгенерирует по шаблону три перегруженных функции с типами:

int max(int x,int y);

float max(float x,float y);

char * max(char *x, char *y);

Экземпляр функции создаётся каждый раз при вызове функции с аргументами, для которых определение не найдено. Если имеется точное определение обычной функции, то в её вызов вставляется тело программы. Особенности возникают, когда в качестве параметров передаются строки. Функция сравнивает два указателя, а не содержимое строк в кодировке ASCII “папа”>”мама”. В действительности результат зависит от того, в какой последовательности компилятор размещает в памяти указанные строки.

Чтобы не производить бессмысленного сравнения двух указателей для строк, можно перегрузить функцию max следующим образом:

char *max(char *x, char *y)

{return (strcmp(x,y)>0?x:y;}

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

7.9 Использование шаблонов с двумя типами параметров

Если подставляемые параметры окажутся разных типов, то компилятор не сможет создать реализацию шаблона. В этом случае в шаблоне указывется несколько фиктивных имен типов параметров.

#include <iostream>

template <class T1, class T2>

T1 max(T1 x, T2 y)

{if (x>=y) return x;

return y;}

main()

{int i=5; long l=123456;

float d=5.5;

cout<<”максимум =”<<max(d,i);

Соседние файлы в папке Экзамен