Программирование на C и C++

Онлайн справочник программиста на C и C++

Новые операторы приведения типов

Хотя С++ полностью поддерживает традиционное приведение типов языка С, для него определе­ны четыре дополнительных оператора приведения типов. Ими являются: const_cast, dynamic_cast, reinterpret_cast и static_cast. Общая форма записи имеет следующий вид:

const_cast <тип> (объект)
dynamic_cast <тип> (объект)
reinterpret_cast <тип> (объект)
static_cast <тип> (объект)

Здесь тип определяет целевой тип, а объект является объектом, приводимым к новому типу.

Оператор const_cast используется для явного переопределения const и/или volatile в операции приведения типа. Целевой тип должен быть тем же самым, что и исходный тип, за исключением его атрибута const или volatile. Наиболее общеупотребительным использованием const_cast явля­ется удаление атрибута const.

Оператор dynamic_cast выполняет приведение типов во время исполнения с проверкой возмож­ности приведения типа. Если такое приведение не может быть сделано, то выражение принимает значение NULL. Его основным применением служит приведение полиморфных типов. Например, пусть имеются два полиморфных класса В и D, где D выведено из В. Оператор dynamic_cast всегда может привести указатель D* к указателю В*. Оператор dynamic_cast может привести указатель В* к указателю D* только в том случае, если указатель фактически указывает на объект D. В общем случае оператор dynamic_cast выполняет успешное приведение типа, если требуемое полиморфное приведение типа допустимо, т. е. если целевой тип может быть применен к исходному типу объек­та. Если приведение типа невозможно, то dynamic_cast приобретает значение NULL.

Оператор static_cast выполняет не полиморфное приведение типов. Например, он может ис­пользоваться для приведения указателя на базовый класс к указателю на производный класс. Он также может использоваться для любого стандартного указателя. Никаких проверок времени ис­полнения не выполняется. Оператор reinterpret_cast изменяет один тип в фундаментально иной тип. Например, он может быть использован для преобразования указателя в целое число. Опера­тор reinterpret_cast предназначен для использования при приведении типов указателей, несопо­ставимых в отношении наследования.

Только оператор const_cast может убрать атрибут const, что не может выполнить ни оператор dynamic_cast, ни static_cast, ни reinterpret_cast.

Следующая программа демонстрирует использование оператора dynamic_cast:

#include <iostream.h>
#define NUM_EMPLOYEES 4
class employee {
public:
employee () { cout << "Constructing employee\n"; }
virtual void print() = 0;
};
class programmer : public employee {
public:
programmer() { cout << "Constructing programmer\n"; }
void print () { cout << "Printing programmer object\n"; }
};
class salesperson : public employee {
public:
salesperson () { cout << "Constructing salesperson\n"; }
void print() { cout << "Printing salesperson object\n"; }
};
class executive : public employee {
public:
executive () { cout << "Constructing executive\n"; }
void print () { cout << "Printing executive object\n"; }
};
int main() {
programmer prog1, prog2;
executive ex;
salesperson sp;
// инициализация массива служащих
employee *e[NUM_EMPLOYEES];
e[0] = &prog1;
e[1] = &sp;
e[2] = &ex;
e[3] = &prog2;
// просмотр на предмет выяснения, кто является программистом
for (int i = 0; i < NUM_EMPLOYEES; i + +) {
programmer *pp = dynamic_cast<programmer*>(e[i]);
if(pp) {
cout << "Is a programmer\n";
pp->print();
}
else {
cout << "Not a programmer\n";
}
}
}

Массив e содержит указатели на четырех работников. Оператор dynamic_cast используется для идентификации того, кто из них является программистом. Если оператор dynamic_cast возвращает NULL, то работник не является программистом. В противном случае вызывается функция print(). Программа выдаст следующий результат на дисплей:

Constructing employee
Constructing programmer
Constructing employee
Constructing programmer
Constructing employee
Constructing executive
Constructing employee
Constructing salesperson
Is a programmer
Printing programmer object
Not a programmer
Not a programmer
Is a programmer
Printing programmer object

Следующая программа демонстрирует использование оператора reinterpret_cast:

// пример использования reinterpret_cast
#include <iostream.h>
int main()
{
int i;
char *p = "This is a string";
i = reinterpret_cast<int> (p); // преобразование указателя к целому
cout << i;
return 0;
}

Хотя новые операторы приведения типов не требуются для наиболее простых программ, они могут оказаться полезными в более сложных приложениях С++.