БлогNot. C++: шпаргалка по кастам

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;
}

теги: c++ программирование

01.09.2019, 15:02; рейтинг: 51