C++: шпаргалка по кастам
...то есть, по стандартным преобразованиям типа, которых насчитывается четыре.
Упрощая, можно сказать, что операция dynamic_cast предназначена для преобразование полиморфных типов данных, например, классов, и применяется к указателям или ссылкам.
Вот типичный пример, где сравнивается "классическое" преобразование типа и dynamic_cast
. Класс Derived
наследует классу Base
с атрибутом public
.
Из комментариев видно, что классический способ с круглыми скобками работает "в обе стороны", и при преобразовании указателя на объект родительского класса к дочернему и наоборот. Операция dynamic_cast
в первом случае не работает, что защищает нас от потенциально некорректного преобразования типов (например, при составлении списков разнотипных объектов нужно всегда преобразовывать тип данных к родительскому).
Коды проверялись в Dev C++ 4.9.X, Visual Studio 2015, QT 5.10.X
/* классическое преобразование типа и dynamic_cast - преобразование полиморфных типов */ #include <iostream> using namespace std; class Base { virtual void show() { cout << "Base" << endl; } }; class Derived : public Base { virtual void show() { cout << "Derived" << endl; } }; //Над пустыми классами полиморфизм работать не обязан :) int main() { Base b, *bptr; Derived d, *dptr; bptr = &b; dptr = (Derived *) bptr; if (dptr) cout << "Yes" << endl; else cout << "No" << endl; //Yes, bptr показывал на объект родительского класса bptr = &d; dptr = (Derived *) bptr; if (dptr) cout << "Yes" << endl; else cout << "No" << endl; //Yes, bptr показывал на объект дочернего класса bptr = &b; dptr = dynamic_cast <Derived *> (bptr); if (dptr) cout << "Yes" << endl; else cout << "No" << endl; //No, bptr показывал на объект родительского класса bptr = &d; dptr = dynamic_cast <Derived *> (bptr); if (dptr) cout << "Yes" << endl; else cout << "No" << endl; //Yes, bptr показывал на объект дочернего класса cin.get(); return 0; }
Простейшее назначение операции const_cast - снять модификатор const там, где он мешает выполнению операции над объектом. Пример:
#include <iostream> using namespace std; void f (const int *p) { int *v = const_cast <int *> (p); *v = 1; //Теперь *v можно менять } int main() { int x = 0; f (&x); cout << x; //1 cin.get(); return 0; }
Операция static_cast осуществляет явное допустимое приведение типов данных, работая подобно встроенному преобразованию типов.
#include <iostream> using namespace std; int main() { int i; double f = 1.5; i = static_cast <int> (f); cout << i; //1 cin.get(); return 0; }
Наконец, reinterpret_cast - это фундаментальное преобразование "несовместимых" типов, сохраняющее битовое значение величины. В примере char *
"преобразуется" в int
.
#include <iostream> using namespace std; int main() { int i; char *s = "Строка текста"; i = reinterpret_cast <int> (s); cout << i; //4456448 или другое :) cin.get(); return 0; }
01.09.2019, 15:02 [1958 просмотров]