static_cast в C ++ | Операторы приведения типов
Оператор Cast - это унарный оператор, который заставляет один тип данных преобразовываться в другой тип данных.
C ++ поддерживает четыре типа приведения типов:
1. Static Cast
2. Dynamic Cast
3. Const Cast
4. Reinterpret Cast
Статическое приведение: это самый простой тип приведения, который можно использовать. Это преобразование во время компиляции. Оно выполняет такие вещи, как неявное преобразование между типами (например, int в float или указатель на void *), а также может вызывать функции явного преобразования (или неявные).
Например,
#include <iostream> using namespace std; int main() { float f = 3.5; int a = f; // this is how you do in C int b = static_cast < int >(f); cout << b; } |
Выход:
3
Теперь внесем несколько изменений в код.
Если вы скомпилируете код, вы получите ошибку:
[Ошибка] недопустимый static_cast из типа 'char *' в тип 'int *'
Это означает, что даже если вы думаете, что можете каким-то образом привести тип определенного объекта к другому, но это незаконно , static_cast не позволит вам этого сделать.
Возьмем еще один пример преобразования объекта в класс и обратно.
#include <iostream> #include <string> using namespace std; class Int { int x; public : Int( int x_in = 0) : x{ x_in } { cout << "Conversion Ctor called" << endl; } operator string() { cout << "Conversion Operator" << endl; return to_string(x); } }; int main() { Int obj(3); string str = obj; obj = 20; string str2 = static_cast <string>(obj); obj = static_cast <Int>(30); return 0; } |
Запустите приведенный выше код:
Преобразование Ctor называется Оператор преобразования Преобразование Ctor называется Оператор преобразования Преобразование Ctor называется
Давайте попробуем понять вышеприведенный вывод:
- Когда создается объект obj, вызывается конструктор, который в нашем случае также является конструктором преобразования (для C ++ 14 правила немного изменены).
- Когда вы создаете str из obj , компилятор не выдаст ошибку, поскольку мы определили оператор преобразования.
- Когда вы делаете
obj=20
, вы фактически вызываете конструктор преобразования. - Когда вы делаете str2 из static_cast , это очень похоже на
string str=obj;
, но с тщательной проверкой типов. - Когда вы пишете
obj=static_cast<Int>(30)
, вы конвертируете 30 в Int с помощью static_cast.
Возьмем пример, связанный с наследованием.
#include <iostream> using namespace std; class Base { }; class Derived : public Base { }; int main() { Derived d1; Base* b1 = (Base*)(&d1); // allowed Base* b2 = static_cast <Base*>(&d1); return 0; } |
Приведенный выше код будет компилироваться без ошибок.
- Мы взяли адрес
d1
явно поместили его вBase
и сохранили вb1
. - Мы взяли адрес
d1
и использовали static_cast, чтобы преобразовать его вBase
и сохранили вb2
.
Поскольку мы знаем, что static_cast выполняет тщательную проверку типов, давайте немного изменим код, чтобы увидеть это:
#include <iostream> using namespace std; class Base { }; class Derived : private Base { // Inherited private/protected not public }; int main() { Derived d1; Base* b1 = (Base*)(&d1); // allowed Base* b2 = static_cast <Base*>(&d1); return 0; } |
Попробуйте скомпилировать приведенный выше код, что вы видите ?? Ошибка компиляции !!!!!!!
[Ошибка] База данных недоступна для производной базы.
Приведенный выше код не будет компилироваться, даже если вы унаследуете защищенный . Итак, чтобы использовать static_cast, наследуйте его как общедоступный.
Используйте static_cast для приведения указателя void в и из.
#include <iostream> int main() { int i = 10; void * v = static_cast < void *>(&i); int * ip = static_cast < int *>(v); return 0; } |