Преобразования типов В языке C/C++ имеется несколько операций преобразования типов. Они используются в случае, если переменная одного типа должна рассматриваться как переменная другого типа. Преобразование типов потенциально может привести к возникновению ошибок. Его использование не рекомендуется.
Приведение типов в стиле 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); }
Операция const_cast Используется для удаления модификатора const. Обычно используется для передачи константного указателя в функцию в качестве параметра, соответствующего обычному указателю. const_cast выражение. void print (int *p) { cout
Операция static_cast Используется вместо приведения типов C, а также для преобразования между указателями и ссылками на объекты одной иерархии. static_cast выражение; float d =static_cast (1)/7;
Пример преобразования типов в иерархии классов class dog : public animal { public: … void guard() { say(); coutguard(); static_cast (f)->guard(); //static_cast (c)->guard(); return 0; } Возможно также обратное преобразование из указателя (или ссылки) на производный класс в базовый. Недостаток статического преобразования - отсутствует контроль за правильностью применения преобразования
Операция dynamic_cast Выполняет преобразование между классами одной иерархии. Результат преобразования может быть проверен. Если объект не может быть преобразован к указанному типу, то возвращается нулевая ссылка. int main() { animal * f = new dog ("filya"); animal * c = new cat ("murka"); dog * d = dynamic_cast (f); if (d) d->guard(); else cout
Динамическое определение типа В С++ определена операция typeid, которая возвращает ссылку на объект класса type_info. У класса type_info есть метод name() – имя типа. Для объектов класса type_info определено сравнение на равенство и неравенство. cout
Шаблоны функций Многие алгоритмы не зависят от типов данных, с которыми работают. Например, вычисление максимального элемента или сортировка. В этом случае можно написать несколько перегруженных функций, но в таком случае один и тот же код придется много раз писать. int max (int a, int b) { if (a>b) return a; else return b; } В С++ можно описать шаблон – семейство функций, которые зависят от типа данных. Конкретный тип данных передается в виде параметра на этапе компиляции. Компилятор автоматически создает код, соответствующий переданному типу.
Описание шаблона функции template заголовок { // тело функции } Может быть несколько параметров, как типов, так и переменных.
Пример использования шаблона template 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
Обработка шаблона Первый вызов функции приводит к созданию компилятором кода для версии функции соответствующего типа. Этот процесс называется инстанцирование шаблона. Тип инстанцирования либо определяется автоматически исходя из типов параметров, либо задается явно.
Шаблоны классов В С++ можно использовать шаблоны классов template class имя_класса { // поля и методы используют аргумент тип };
Пример: стек данных произвольных типов #include template 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
Использование шаблонов классов Классы инстанцируются при описании объектов. Шаблоны методов не могут быть виртуальными. Если для определенного типа существует более эффективный код, то можно использовать специализацию шаблона.