где
— это результирующий тип преобразования, а
— приводимое значение. Если
— ссылка, то результат l-значение.
может быть одним из следующих: static_cast
, dynamic_cast
, const_cast
и reinterpret_cast
. Приведение dynamic_cast
, обеспечивающее идентификацию типов времени выполнения, рассматривается в разделе 19.2.
определяет, какое преобразование осуществляется.
static_cast
Любое стандартное преобразование типов, кроме задействующего спецификатор const
нижнего уровня, можно затребовать, используя оператор static_cast
. Например, приведя тип одного из операндов к типу double
, можно заставить выражение использовать деление с плавающей точкой:
//
double slope = static_cast
Оператор static_cast
зачастую полезен при присвоении значения большего арифметического типа переменной меньшего. Приведение сообщает и читателю программы, и компилятору, что мы знаем и не беспокоимся о возможной потере точности. При присвоении большего арифметического типа меньшему компиляторы зачастую выдают предупреждение. При явном приведении предупреждающее сообщение не выдается.
Оператор static_cast
полезен также при выполнении преобразований, которые компилятор не выполняет автоматически. Например, его можно использовать для получения значения указателя, сохраняемого в указателе void*
(см. раздел 2.3.2):
void* p = &d //
//
//
double *dp = static_cast
После сохранения адреса в указателе типа void*
можно впоследствии использовать оператор static_cast
и привести указатель к его исходному типу, что позволит сохранить значение указателя. Таким образом, результат приведения будет равен первоначальному значению адреса. Однако следует быть абсолютно уверенным в том, что тип, к которому приводится указатель, является фактическим типом этого указателя; при несоответствии типов результат непредсказуем.
const_cast
Оператор const_cast
изменяет только спецификатор const
нижнего уровня своего операнда (см. раздел 2.4.3):
const char *pc;
char *p = const_cast
//
Принято говорить, что приведение, преобразующее константный объект в неконстантный, "сбрасывает const
". При сбросе константности объекта компилятор больше не будет препятствовать записи в этот объект. Если объект первоначально не был константным, использование приведения для доступа на запись вполне допустимо. Но применение оператора const_cast
для записи в первоначально константный объект непредсказуемо.
Только оператор const_cast
позволяет изменить константность выражения. Попытка изменить константность выражения при помощи любого другого именованного оператора приведения закончится ошибкой компиляции. Аналогично нельзя использовать оператор const_cast
для изменения типа выражения:
const char *cp;
//
char *q = static_cast
static_cast
const_cast
//
Оператор const_cast
особенно полезен в контексте перегруженных функций, рассматриваемых в разделе 6.4.
reinterpret_cast
Оператор reinterpret_cast
осуществляет низкоуровневую интерпретацию битовой схемы своих операндов. Рассмотрим, например, следующее приведение:
int *ip;
char *pc = reinterpret_cast
Никогда не следует забывать, что фактическим объектом, на который указывает указатель pc
, является целое число, а не символ. Любое использование указателя pc
, подразумевающее, что это обычный символьный указатель, вероятно, потерпит неудачу во время выполнения. Например, следующий код, вероятней всего, приведет к непредвиденному поведению во время выполнения:
string str(pc);