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


Преобразование типов в С++ (49 KB)

