Оператор static_cast
Преобразовывает expression в тип type-id,, опираясь только на типы, которые содержатся в выражении.
static_cast <type-id> ( expression )
Заметки
В стандартном языке C++, проверка типа во время выполнения не выполняется, что обеспечивает безопасность преобразования. В C ++/CX выполняются проверки во время компиляции и во время выполнения. Дополнительные сведения см. в разделе Приведение (C++/CX).
Оператор static_cast можно использовать для таких операций, как преобразование указателя на базовый класс в указатель на производный класс. Такие преобразования не всегда являются безопасными.
Обычно static_cast используется, когда требуется преобразовать числовые типы данных, например перечисления в целые числа или целые числа в числа с плавающей запятой, и при полной уверенности в том, какие типы данных используются в преобразовании. Преобразования static_cast не так безопасны, как преобразования dynamic_cast, поскольку static_cast не выполняет проверку типа во время выполнения, а dynamic_cast выполняет. Применение dynamic_cast к неоднозначному указателю завершится ошибкой, тогда как static_cast возвращает результат, как будто бы все в порядке; это может быть опасно. Хотя преобразования dynamic_cast более безопасны, dynamic_cast работает только с указателями или ссылками, а проверка типа во время выполнения является дополнительной нагрузкой. Дополнительные сведения см. в разделе Оператор dynamic_cast.
В следующем примере строка D* pd2 = static_cast<D*>(pb); небезопасна, поскольку D может иметь поля и методы, не входящие в B. Однако строка B* pb2 = static_cast<B*>(pd); является безопасным преобразованием, поскольку D всегда содержит все B.
// static_cast_Operator.cpp
// compile with: /LD
class B {};
class D : public B {};
void f(B* pb, D* pd) {
D* pd2 = static_cast<D*>(pb); // Not safe, D can have fields
// and methods that are not in B.
B* pb2 = static_cast<B*>(pd); // Safe conversion, D always
// contains all of B.
}
В отличие от dynamic_cast проверка во время выполнения не выполняется в преобразовании static_cast с pb. Объект, на который указывает pb, может не быть объектом типа D, и в этом случае использование *pd2 может привести ужасным последствиям. Например, вызов функции, являющейся членом класса D, но не класса B, может привести к нарушению прав доступа.
Операторы dynamic_cast и static_cast перемещают указатель по всей иерархии классов. Однако static_cast основывается только на сведениях, предоставленных в операторе приведения и поэтому может быть небезопасно. Например:
// static_cast_Operator_2.cpp
// compile with: /LD /GR
class B {
public:
virtual void Test(){}
};
class D : public B {};
void f(B* pb) {
D* pd1 = dynamic_cast<D*>(pb);
D* pd2 = static_cast<D*>(pb);
}
Если pb действительно указывает на объект типа D, pd1 и pd2 получат одно и то же значение. Также они получат одно и то же значение, если pb == 0.
Если pb указывает на объект типа B, а не на полный класс D, у dynamic_cast будет достаточно информации, чтобы вернуть ноль. Однако static_cast основывается на утверждении программиста, что pb указывает на объект типа D и просто возвращает указатель на этот предполагаемый объект D.
Соответственно, static_cast может выполнить операции, обратные неявным преобразованиям, и в таком случае результаты не будут определены. Необходимость убедиться в том, что результаты преобразования static_cast безопасны, возлагается на программиста.
Это поведение также применяется к типам, отличным от типов класса. Например, static_cast можно использовать для преобразования из int в char. Однако полученный char может иметь недостаточно бит для хранения всего значения int. Опять же, необходимость убедиться в том, что результаты преобразованияstatic_cast безопасны, возлагается на программиста.
Оператор static_cast также можно использовать для выполнения любого неявного преобразования, включая стандартные преобразования и определенные пользователем преобразования. Например:
// static_cast_Operator_3.cpp
// compile with: /LD /GR
typedef unsigned char BYTE;
void f() {
char ch;
int i = 65;
float f = 2.5;
double dbl;
ch = static_cast<char>(i); // int to char
dbl = static_cast<double>(f); // float to double
i = static_cast<BYTE>(ch);
}
Оператор static_cast может явным образом преобразовывать целое значение в тип перечисления. Если значение типа целого не оказывается в диапазоне значений перечисления, получаемое значение перечисления не определено.
Оператор static_cast преобразует значение пустого указателя в значение пустого указателя конечного типа.
Любое выражение можно явно преобразовать или в тип void с помощью оператора static_cast. Тип назначения void может дополнительно включать в себя атрибут const, volatile или __unaligned.
Оператор static_cast не может удалять атрибуты const, volatile и __unaligned. Дополнительные сведения об удалении этих атрибутов см. в разделе Оператор const_cast.
Из-за опасности выполнения непроверенных приведений в дополнение к перемещению сборщика мусора использовать static_cast необходимо только в критическом для производительности коде при наличии уверенности, что его работа будет верной. Если необходимо использовать static_cast в режиме выпуска, замените его safe_cast в отладочных сборках, чтобы гарантировать успешное завершение.