Оператор 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 в отладочных сборках, чтобы гарантировать успешное завершение.

См. также

Ссылки

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

Ключевые слова в C++