Скачиваний:
42
Добавлен:
15.06.2014
Размер:
903.68 Кб
Скачать

21

Пример программы (5)

Элемент множества – целое число

class Integer: public base

{

int i; public:

Integer(int i, int num): base(num) {this -> i = i;}

void print() { cout << i << ' '; } inline int& get() { return i; }

};

Элемент множества – строка символов

class String: public base

{

char * str; public:

String(char * str, int num): base(num) {this -> str = str;}

void print() { cout << str << ' '; } };

22

Пример программы (6)

Головная программа - тест

void main(int argc, char * argv[])

{

Set* s1= new Set;

int id1=s1->get_id(), id2; Integer* t1= new Integer(1,id1); Integer* t2 = new Integer(5,id1);

String* t3 = new String("str1", id1); String* t4 = new String("str2", id1);

{

Set* s2 = new Set; id2 = s2->get_id();

String* t5 = new String("hello", id2); Integer* t6 = new Integer(12,id2); cout << (*s1) << (*s2);

}

base::printall(id1);

char xxx; cin >> xxx;

}

23

Повтор некоторых деталей - 1

Виртуальная функция и ее порожденные экземпляры, имеющие одну и ту же сигнатуру, должны иметь один и тот же возвращаемый тип. Перекрытие виртуальной функции

называется переопределением.

Внимание! Невиртуальные функции–члены, имеющие ту же самую сигнатуру в порожденных классах, могут иметь

различный возвращаемый тип.

Конструкторы и деструкторы не имеют возвращаемых типов. Тип, возвращаемый перегруженным оператором new должен быть void*. Тип, возвращаемый перегруженным

оператором delete должен быть void.

Все функции-члены, за исключением конструкторов и

перегруженных операторов new и delete, могут быть виртуальными.

Конструкторы, деструкторы, перегруженный operator= и friend функции не наследуются.

24

Повтор некоторых деталей - 2

Перегрузка операторов =, (), [] и -> может быть

выполнена только нестатическими функциями-членами.

Перегрузка операторов new и delete может быть выполнена только статическими функциями-членами. Прочие перегружаемые операторы могут быть выполнены любыми

другими функциями, дружественными или обычными. Операторы ввода/вывода потоков >> и << не могут перегружаться функциями-членами класса – только

дружественными.

Union могут иметь конструкторы и деструкторы, но не виртуальные функции. Union не может ни служить базовым классом, ни иметь базового класса.

Модификация доступа при наследовании возможна, но

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

подтипов. Модификация доступа не может расширять видимость.

25

Повтор некоторых деталей - 3

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

используемых оператором или функцией.

Список параметров функции называется сигнатурой.

При проверке сигнатуры существует три возможности:

наилучшее соответствие, неоднозначное соответствие и отсутствие соответствия. Без наилучшего соответствия

компилятор выдает соответствующую ошибку синтаксиса.

26

Повтор некоторых деталей - 4

Пусть функция print описана как

void print( int i = 0); // сигнатура int

void print( int i, double x); // сигнатура int, double void print(double x, int i); // сигнатура double, int

Вызов:

 

print (‘A’);

// преобразует и соответствует int

print (str[]);

// нет соответствия – неправильный тип

print (15,9);

// неоднозначно

print ();

// соответствует int по умолчанию

print (15, 9.2);

// соответствует int, double

27

Повтор некоторых деталей - 5

Существует два этапа алгоритма выбора соответствия сигнатуры. Первый этап определяет лучшее соответствие для каждого параметра. На втором этапе проверяется, есть ли функция, которая уникально лучше всего соответствует по каждому параметру.

Лучшее соответствие – это значит точное соответствие. Оно также включает в себя и тривиальные преобразования.

 

 

 

 

 

 

 

 

 

 

Из

В

 

 

Из

В

 

 

T

T&

 

 

 

T*

const T*

 

 

T&

T

 

 

 

T*

volatile T*

 

 

T

const T

 

 

 

T&

const T&

 

 

T

volatile T

 

 

 

T&

volatile T&

 

 

 

 

 

 

T[ ]

T*

 

 

 

 

 

 

 

T (параметры)

(*T) (параметры)

 

 

 

 

 

 

 

 

 

 

 

Эти преобразования не могут использоваться для абсолютно однозначного точного соответствия.

28

Повтор некоторых деталей - 6

Алгоритм выбора перегруженных функций:

1.Использовать точное соответствие, если оно найдено.

2.Проверить поддержку стандартных типов

3.Проверить стандартные преобразования типов

4.Проверить преобразования, определяемые

пользователем

5.Использовать соответствие для аргументов, если оно найдено

Тесты …

29

 

Вопрос: Что напечатает программа:

 

 

#include <stdio.h>

 

 

void ampersand( int n, int &k );

Варианты ответа:

 

int main()

(1) Произойдет ошибка во время

 

{

компиляции

 

int n=5;

 

int k=10;

(2) n=5 & k=10

 

ampersand( n, k );

(3) n=5 & k=5

 

printf( "n=%d &k=%d\n", n,

(4) n=5 & k=<адрес переменной в

 

k );

памяти>

 

 

 

return 0;

}

void ampersand( int n, int &k )

{

k -= 5; --n;

}

Тесты …

30

 

Вопрос: Что напечатает программа:

 

 

 

 

#include <stdio.h>

 

 

 

 

void ampersand( int n, int &k );

Варианты ответа:

 

int main()

(1) Произойдет ошибка во время

 

{

компиляции

 

int n=5;

 

int k=10;

(2)

n=5 & k=10

 

 

ampersand( n, k );

(3) n=5 & k=5

 

printf( "n=%d &k=%d\n", n,

(4) n=5 & k=<адрес переменной в

 

k );

памяти>

 

 

 

return 0;

}

void ampersand( int n, int &k )

{

k -= 5; --n;

}