Лекция 9 Приведение типов. Классификация типов Типы С++ Пользовательские Встроенные (Фундаментальные) Адресные Арифтметические void Указатели Ссылки Массивы.

Презентация:



Advertisements
Похожие презентации
Лекция 7 Приведение типов. Классификация типов Типы С++ Пользовательские Встроенные (Фундаментальные) Адресные Арифтметические void Указатели Ссылки Массивы.
Advertisements

Функции Функция – именованная последовательность описаний и операторов, выполняющая некоторое действие. Может иметь параметры и возвращать значение. Функция.
Лекция 5 Адресные типы. Указатели адрес (размещение в памяти) объекта Массивы последовательность однотипных данных Ссылки альтернативное имя объекта.
Преобразования типов В языке C/C++ имеется несколько операций преобразования типов. Они используются в случае, если переменная одного типа должна рассматриваться.
Лекция 8 Область видимости Время жизни. Область видимости Область видимости – характеристика именованного объекта Область видимости - часть текста программы,
Лекция 10 ОбъектыЛекция 10 ОбъектыООП Инкапсуляция Возможность совместного хранения данных и кода для их обработки Наследование Возможность расширять существующие.
Практическое занятие 6. Функции. Большинство языков программирования используют понятия функции и процедуры. C++ формально не поддерживает понятие процедуры,
Лекция 30. Преобразования типов в C++ Красс Александр СПбГУ ИТМО, 2009.
Лекция 10. Введение в ООП. Часть 3 Красс Александр СПбГУ ИТМО, 2008.
©ρŧą Базовые конструкции языка.
Множественное наследование class A {... }; class B {... }; class C : public A, protected B {... }; !!! Спецификатор доступа распространяется только на.
Лекция 6 Функции. Объявления и определения Объявление функции – указание имени функции, а также входных и выходных параметров Определение функции – указание.
Лекция 6 Функции. Объявления и определения Объявление функции – указание имени функции, а также входных и выходных параметров Определение функции – указание.
Инструкции C++ Условная инструкция Формат: if (условие) оператор; else оператор; Пример: if (i!=0) { if (j) j++; if(k) k++; else if(p) k--; } else i--;
УКАЗАТЕЛИ. Переменная - это именованная область памяти с заданным типом. [=значение]; int a; //Переменная типа integer с именем a int b=2;// Переменная.
ЛЕКЦИЯ 7 КЛАССЫ ПАМЯТИ И ОБЛАСТЬ ДЕЙСТВИЯ ОБЪЕКТОВ.
©Павловская Т.А. Язык С++ Курс «С++. Программирование на языке высокого уровня» Павловская Т.А.
Синтаксис языка Java. Символы и синтаксис Перевод строчки эквивалентен пробелу Регистр в именах различается.
Лекция 10 Структуры. Классификация типов данных Простые Целые, вещественные, void, перечисления Являются атомарными не состоят из других типов Адресные.
Прикладное программирование кафедра прикладной и компьютерной оптики Полиморфизм.
Транксрипт:

Лекция 9 Приведение типов

Классификация типов Типы С++ Пользовательские Встроенные (Фундаментальные) Адресные Арифтметические void Указатели Ссылки Массивы С плавающей точкой Интегральные double int char enum struct class struct class bool float

Виды приведений Явное Преобразование произвольных типов с указанием оператора приведения C++-style – static_cast – reinterpret_cast – const_cast – dynamic_cast С-style Неявное Преобразование встроенных типов без явного указания оператора приведения

Явное С++-style приведение Статическое приведение static_cast Преобразование «родственных» типов: указатель на потомка в указатель на родителя (восходящее преобразование) указатель на void в любой другой указатель дробного в интегральный интегральный в перечисление Слепое приведение reinterpret_cast Преобразование с сохранением битового представления, невыполнимое явно или при помощи static_cast Снятие квалификаторов const_cast Снятие квалификаторов const и volatile Полиморфное приведение dynamic_cast Нисходящее преобразование при наследовании

Примеры явного С++ приведения int d = static_cast ( 7.5 ); int const * cpd = &d ; int * pd = const_cast ( cpd ); float f = static_cast ( d ); float * pf = reinterpret_cast ( pd ); float * pf2 = static_cast ( static_cast (pd) ); float h = *reinterpret_cast ( &d ); int d = static_cast ( 7.5 ); int const * cpd = &d ; int * pd = const_cast ( cpd ); float f = static_cast ( d ); float * pf = reinterpret_cast ( pd ); float * pf2 = static_cast ( static_cast (pd) ); float h = *reinterpret_cast ( &d );

Явное С-style приведение Cast-форма (T)e Любое преобразование, которое может быть выражено через комбинацию static_cast, reinterpret_cast и const_cast. Функциональная форма T(e) Для встроенных типов идентична (T)e Для пользовательских типов вызывает соответствующий конструктор Для встроенных типов форма T() означает инициализацию нулем int n = (int)7.6 ; void const * const pv = 0 ; float * pr = (float *)pv; int n_ptr = (int)pv ; int n = (int)7.6 ; void const * const pv = 0 ; float * pr = (float *)pv; int n_ptr = (int)pv ; int n = int(7.6) ; int q = int(); typedef float* float_ptr ; float * pr = float_ptr(7); int n = int(7.6) ; int q = int(); typedef float* float_ptr ; float * pr = float_ptr(7);

Неявное преобразование Применение Инициализация переменных Преобразование аргументов функций Вычисление значения выражения Приводятся типы: Арифметические (без потери точности) Перечислимые к интегральным Указатели к указателям на void Произвольные типы к идентичным с квалификатором const

Указатель на void Переменные типа void* нельзя разыменовывать Указатель на любой объект можно присвоить переменной типа void* Переменную типа void* можно присвоить другой переменной типа void* Две переменных типа void* можно сравнивать на равенство и неравенство void* можно явно преобразовать в другой тип int n = 0 ; int * pn = &n ; *pn = 7 ; // Можно void * pv = pn ; *pv = 9 ; // Нельзя! float * pf = pv ; float * pq = pn ; float * pr = (float *)pv; int n = 0 ; int * pn = &n ; *pn = 7 ; // Можно void * pv = pn ; *pv = 9 ; // Нельзя! float * pf = pv ; float * pq = pn ; float * pr = (float *)pv;

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

Правила разрешения вызова 1.Точное соответствие типа Тип фактического аргумента соответствует типу формального полностью или с тривиальным преобразованием (массив к указателю, T к const T) 2.Соответствие с помощью продвижения в группе Фактический и формальный аргумент принадлежат одной группе арифметических типов, и формальный «больше» фактического. Например, float->double, char->int, short->int и т.п. 3.Соответствие с помощью неявного преобразования Существует неявное преобразование, приводящее фактический аргумент к формальному 4.Соответствие с помощью пользовательского преобразования Существует объявленное пользователем преобразование, приводящее фактический аргумент к формальному 5.Соответствие неуказанным аргументам Формальный аргумент объявлен как...

Разрешение вызова Разрешение вызова при одном аргументе Осуществляется поиск функции с соответствующим аргументом в порядке указания правил. Если для правила не нашлось соответствия, переходим к следующему Если для правила найдено одно соответствие, оно и используется Если для правила есть более одного соответствия, это считается неоднозначностью вызова (ambiguous call) Разрешение вызова при многих аргументах Осуществляется поиск по каждому аргументу Выбирается функция с наиболее хорошим совпадением одного аргумента, а остальные аргументы имеют не худшее совпадение.

Примеры перегрузки void print (int); void print (const char *); void print (double); void print (long); void print (char); void f ( char c, int i, short s, float f ) { print (c); // точное, (5) print (i); // точное, (1) print (s); // продвижение, (1) print (f); // продвижение, (3) print (a); // точное (5) print (49L); // точное (4) print (0); // точное (1) print (a); // точное (2) } void print (int); void print (const char *); void print (double); void print (long); void print (char); void f ( char c, int i, short s, float f ) { print (c); // точное, (5) print (i); // точное, (1) print (s); // продвижение, (1) print (f); // продвижение, (3) print (a); // точное (5) print (49L); // точное (4) print (0); // точное (1) print (a); // точное (2) }

Примеры File1.cpp File2.cpp int a ; // внешняя линковка, используется в file1.cpp extern int c ; // ошибка (с не определена) int d ; // ошибка (d определена дважды) double eight ; // ошибка – внешнее имя из file1.cpp static int bar = 7 ; // все хорошо – внутренняя комп. int sum (int a, int b) // функция с внешней компоновкой { return a + b ; } void foo () {}; // функция с внешней компоновкой int a ; // внешняя линковка, используется в file1.cpp extern int c ; // ошибка (с не определена) int d ; // ошибка (d определена дважды) double eight ; // ошибка – внешнее имя из file1.cpp static int bar = 7 ; // все хорошо – внутренняя комп. int sum (int a, int b) // функция с внешней компоновкой { return a + b ; } void foo () {}; // функция с внешней компоновкой int sum(int, int); // объявление ф-ции и другой единицы extern int a ; // внешняя a (из file2.cpp) extern int c ; // ошибка (с не определена) int d ; // ошибка (d определена дважды) int eight () { return sum(3,5); } // Ok void bar () { foo(); } // Ошибка: foo не определена int sum(int, int); // объявление ф-ции и другой единицы extern int a ; // внешняя a (из file2.cpp) extern int c ; // ошибка (с не определена) int d ; // ошибка (d определена дважды) int eight () { return sum(3,5); } // Ok void bar () { foo(); } // Ошибка: foo не определена