'

Преобразования типов

Понравилась презентация – покажи это...





Слайд 0

Преобразования типов В языке C/C++ имеется несколько операций преобразования типов. Они используются в случае, если переменная одного типа должна рассматриваться как переменная другого типа. Преобразование типов потенциально может привести к возникновению ошибок. Его использование не рекомендуется.


Слайд 1

Приведение типов в стиле C Операция может записываться в двух формах: тип(выражение) или (тип) выражение. Например float c = double(1)/7; float d = (double)1/7; Приведение типов чаще всего используется для преобразования нетипизированного указателя (на void) в типизированный. Например функция сравнения строк для сортировки выглядит так: int cmp (const void *a, const void *b) { return strcmp( (const char *) a, (const char *) b); }


Слайд 2

Операция const_cast Используется для удаления модификатора const. Обычно используется для передачи константного указателя в функцию в качестве параметра, соответствующего обычному указателю. const_cast <тип> выражение. void print (int *p) { cout << *p; } int main() { int t = 10; const int *p = &t; print (const_cast <int *>(p)); }


Слайд 3

Операция static_cast Используется вместо приведения типов C, а также для преобразования между указателями и ссылками на объекты одной иерархии. static_cast <тип> выражение; float d =static_cast<double>(1)/7;


Слайд 4

Пример преобразования типов в иерархии классов class dog : public animal { public: … void guard() { say(); cout<< "rrrrrrr..." <<endl;} }; int main() { animal * f = new dog ("filya"); f->say(); f->hungry(); // f->guard(); static_cast <dog *> (f)->guard(); // static_cast <dog *> (c)->guard(); return 0; } Возможно также обратное преобразование из указателя (или ссылки) на производный класс в базовый. Недостаток статического преобразования - отсутствует контроль за правильностью применения преобразования


Слайд 5

Операция dynamic_cast Выполняет преобразование между классами одной иерархии. Результат преобразования может быть проверен. Если объект не может быть преобразован к указанному типу, то возвращается нулевая ссылка. int main() { animal * f = new dog ("filya"); animal * c = new cat ("murka"); dog * d = dynamic_cast <dog *> (f); if (d) d->guard(); else cout <<"error"; dog * e = dynamic_cast <dog *> (c); if (e) e->guard(); else cout <<"error"; return 0; }


Слайд 6

Динамическое определение типа В С++ определена операция typeid, которая возвращает ссылку на объект класса type_info. У класса type_info есть метод name() – имя типа. Для объектов класса type_info определено сравнение на равенство и неравенство. cout << typeid (*f). name() <<endl;


Слайд 7

Шаблоны функций Многие алгоритмы не зависят от типов данных, с которыми работают. Например, вычисление максимального элемента или сортировка. В этом случае можно написать несколько перегруженных функций, но в таком случае один и тот же код придется много раз писать. int max (int a, int b) { if (a>b) return a; else return b; } В С++ можно описать шаблон – семейство функций, которые зависят от типа данных. Конкретный тип данных передается в виде параметра на этапе компиляции. Компилятор автоматически создает код, соответствующий переданному типу.


Слайд 8

Описание шаблона функции template <class тип> заголовок { // тело функции } Может быть несколько параметров, как типов, так и переменных.


Слайд 9

Пример использования шаблона template <class T> T max (T a, T b) { if (a>b) return a; else return b; } int main() { int a=10, b = 5; double c = 3, d = 10; cout << max(a,b) <<endl; cout << max(c,d) <<endl; // cout << max(a,d) <<endl; cout << max<double>(a,d) <<endl; return 0; }


Слайд 10

Обработка шаблона Первый вызов функции приводит к созданию компилятором кода для версии функции соответствующего типа. Этот процесс называется инстанцирование шаблона. Тип инстанцирования либо определяется автоматически исходя из типов параметров, либо задается явно.


Слайд 11

Шаблоны классов В С++ можно использовать шаблоны классов template <class тип> class имя_класса { // поля и методы используют аргумент тип };


Слайд 12

Пример: стек данных произвольных типов #include <iostream.h> template <class Data = char, int Max = 1000> class stack { private: Data st[Max]; int top; public: stack (): top(0) {} void push(Data x) { st[top++] = x; } Data pop() { return st[--top]; } bool empty() { return (top == 0);} }; int main() { stack <> s1; s1.push('a'); s1.push('b'); s1.push('c'); cout << "1: " << s1.pop() << endl; cout << "2: " << s1.pop() << endl; cout << "3: " << s1.pop() << endl; stack <int, 100> s2; s2.push(1); s2.push(2); s2.push(3); while (! s2.empty()) cout << s2.pop() << endl; return 0; }


Слайд 13

Использование шаблонов классов Классы инстанцируются при описании объектов. Шаблоны методов не могут быть виртуальными. Если для определенного типа существует более эффективный код, то можно использовать специализацию шаблона.


×

HTML:





Ссылка: