- static_cast
(expression) - dynamic_cast
(expression) - const_cast
(expression) - reinterpret_cast
(expression)
static_cast相当于传统的C语言里的强制转换,该运算符把expression转换为new_type类型,用来强迫隐式转换,但没有运行时类型检查来保证转换的安全性。
它主要有如下几种用法:
static_cast不能转换掉expression的const、volatile。
如果涉及到类的话,static_cast只能在有相互联系的类型中进行相互转换,不一定包含虚函数。
- /* 常规的使用方法 */
- float f_pi=3.141592f
- int i_pi=static_cast<int>(f_pi); /// i_pi 的值为 3
-
- /* class 的上下行转换 */
- class Base{
- // something
- };
- class Sub:public Base{
- // something
- }
-
- // 上行 Sub -> Base
- //编译通过,安全
- Sub sub;
- Base *base_ptr = static_cast
(&sub); -
- // 下行 Base -> Sub
- //编译通过,不安全
- Base base;
- Sub *sub_ptr = static_cast(&base);
主要用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换(只能用于类间转换,支持类间交叉转换,不能操作普通数据。)(转换之后可以调用转换之后对象的函数)
(1)在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
Dynamic_cast操作符则可以在运行期对可能产生问题的类型转换进行测试。(2)发生多态时,允许互相转换。
(3)无继承关系的类之间也可以相互转换,类之间的交叉转换。
(4)如果dynamic_cast语句的转换目标是指针类型并且失败了,则结果为null指针。如果转换目标是引用类型并且失败了,则dynamic_cast运算符将抛出一个std::bad_cast异常
(5)使用 dynamic_cast 进行转换的,基类中一定要有虚函数,否则编译不通过(类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的情况,此时转换才有意义)。这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表。
- class base {
- public:
- void print1() { cout << "in class base" << endl; }
- };
-
- class derived : public base {
- public:
- void print2() { cout << "in class derived" << endl; }
- };
-
- int main() {
- derived* p, * q;
- // p = new base; // Compilr Error: 无法从 "base * " 转换为 "derived * "
-
- // Compile Error: Cannot cast from 'base*' to 'derived*' via dynamic_cast: expression type is not polymorphic(多态的)
- // p = dynamic_cast
(new base); -
- q = static_cast
(new base); // ok, but not recommended(推荐) -
- q->print1(); // in class base
- q->print2(); // in class derived
-
- return 0;
- }
-
- #include
- #include
- using namespace std;
-
- class Base
- {
- public:
- virtual ~Base() {} //有虚函数,因此是多态基类
- };
-
- class Derived : public Base { };
-
- int main()
- {
- Base b;
- Derived d;
- Derived* pd;
-
- pd = reinterpret_cast
(&b); // 此处pd不会为 NULL。reinterpret_cast不检查安全性,总是进行转换 - if (pd == NULL)
- cout << "unsafe reinterpret_cast" << endl; // 不会执行
-
- pd = dynamic_cast
(&b); // 结果会是NULL,因为 &b 不指向派生类对象,此转换不安全 - if (pd == NULL)
- cout << "unsafe dynamic_cast1" << endl; // 会执行
-
- pd = dynamic_cast
(&d); // 安全的转换,此处 pd 不会为 NULL - if (pd == NULL)
- cout << "unsafe dynamic_cast2" << endl; // 不会执行
-
- return 0;
- }
const_cast ,用于修改类型的const或volatile属性,只能对是 引用 或者 指针 的变量添加或移除const。(除了const 或volatile修饰之外, type_id和expression的类型是一样的。)
const_cast则正是用于强制去掉这种不能被修改的常数特性,但需要特别注意的是const_cast不是用于去除变量的常量性,而是去除 指向常数对象的指针或引用 的常量性,其去除常量性的对象必须为指针或引用。
- const int g = 20;
- int *h = const_cast<int*>(&g);//去掉const常量const属性
-
- const int g = 20;
- int &h = const_cast<int &>(g);//去掉const引用const属性
-
- const char *g = "hello";
- char *h = const_cast<char *>(g);//去掉const指针const属性
reinterpret_cast是强制类型转换符用来处理无关类型转换的,并且其不可移植。他是用在任意的指针之间的转换,引用之间的转换,指针和足够大的int型之间的转换,整数到指针的转换。
通过运行时类型信息程序能够使用 基类的指针或引用 来检查这些指针或引用所指的对象的实际派生类型。(运行时类型识别)