强制类型转换

  C++ 在设计中一直强调类型安全,而且也采取了一定的措施来保障这条准则的执行。但是,从C继承而来的强制转型却破坏了C++类型系统,C中的强制转型可谓是“无所不能”,其超强的能力给C++带来了很大的安全隐患。强制转型会引起各种各样的麻烦,有时这些麻烦很容易被察觉,有时它们却又隐藏极深,难以察觉。
  C++兼容C,所以C++提出了自己的一套类型转换机制,分别是:static_cast、reinterpret_cast、const_cast以及dynamic_cast  

1)static_cast

  用于非多态类型的转换,用于两个相关或相近类型间的转换。不能用于两个不相关的类型转换。相当于C中的隐式类型转换

void Test()
{
    int i = 1;
    double d = static_cast<double> (i);
    cout << d << endl;
    d = 1.23;
    i = static_cast<int> (d);
    cout << i << endl;
}

  static_cast可以实现内置基本数据类型的相互转换,如果牵扯到类的话,必须是有相互联系的类,而且向下转型没有动态类型检查,是不安全的。

2)reinterpret_cast

  reinterpret_cast是不相干类型间的转换,是不安全的。主要有三种强制转换用途:改变指针或引用的类型、将指针或引用转换为一个足够长度的整形、将整型转换为指针或引用类型。
  用法:reinterpret_cast (expression)
  type_id必须是一个指针、引用、算术类型、函数指针或者成员指针。可以把指针转换为整数,整数转为指针。

void Test()
{
    int* p = new int(1);
    int i = reinterpret_cast<int>(p);
    p = reinterpret_cast<int*>(i);
    cout << i << endl;
    cout << p << endl;
}

3)const_cast

  在C语言中,const限定符通常被用来限定变量,用于表示该变量的值不能被修改
  而const_cast则正是用于强制去掉这种不能被修改的常数特性,但需要特别注意的是const_cast不是用于去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,其去除常量性的对象必须为指针或引用
  并且const_cast不能用来执行任何类型的转换的,只能调节类型限定符,这样会引起编译错误的! 

void Test()
{
    const int a = 1;
    int* p = const_cast<int*>(&a);
    *p = 3;
    a = 2;//error,const_cast修改的是指向常数对象的指针或引用属性,不会更改原来变量的属性
    double d = const_cast<double*>(&a);//error,试图类型转换
}

4)dynamic_cast

  1. dynamic_cast用于将一个父类对象的指针转换为子类对象的指针或引用(动态转换)
  2. 向上转型:子类对象指针->父类指针/引用(不需要转换)
  3. 向下转型:父类对象指针->子类指针/引用(用dynamic_cast是安全的)
  4. dynamic_cast是运行时处理的,运行时要进行类型检查
  5. 使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。
    基类中需要检测有虚函数的原因:类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的情况,此时转换才有意义。
  6. 在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
  7. 当父类指针转换成子类的指针时,会先检查是否能够转换成功,如果能够转换成功,就将其转换,如果不能,就返回0
class Basic {
public:
    Basic()
    {}
    int b;
    virtual void func()
    {
        cout << "Basic::func()" << endl;
    }
};
class Student :public Basic {
    void func() 
    {
        cout << "Student::func()" << endl;
    }
    int c;
};
void Test()
{
    Basic* b;
    Student* s;
    s = dynamic_cast(b);
}

5)总结

1.去const属性用const_cast
2.基本类型转换用static_cast
3.多态类之间的类型转换用daynamic_cast
4.不同类型的指针类型转换用reinterpreter_cast

6)explicit 关键字

  explicit关键字阻止经过转换构造函数进行的隐式转换的发生,声明为explicit的构造函数不能在隐式转换中使用。

你可能感兴趣的:(强制类型转换,static_cast,C++学习笔记)