看书看得有些迷茫,总结如下:
C++11当中,类型转换有4中,如果再算上C风格类型转换,那就是5种。常用应用场景排序如下(按常用程度排序):
1. C风格类型转换,例子如下:
int i;
double d;
i = (int)(d); // 或者 i = (int)d; 或者 i = int(d);
最好就在int,double ,long ,string,这种基本数据类型中用用。虽然它也可以用在类指针身上,但是类指针的问题,就是C++中4个新的转换符所要解决的问题。
2.reinterpret_cast
直译过来,就是重新解释_转换。范围最广,后续几个转换符都是针对各自场景多了些检查与转换。
应用场景:该操作符能在非相关类型之间转换,因为他不对类型之间指向的内容做任何的检查与转换,只是简单的从一个指针到另外一个指针的值得二进制拷贝,伪代码如下:
class A{xxxx};
class B{xxxx};
A *pa = new A();
B *pb = new B();
pb = reinterpret_cast<B *>(pa);
注意,reinterpret_cast,是将一个指针,转换成另一个指针。输入的是指针类型,输出的,也是指针类型。
3.static_cast
直译过来就是:静态_转换。允许执行任意的隐式转换和相反的转换。
应用场景:父类子类之间相互转换,以及在基础类型转换时,不喜欢用C风格类型转换时可以用他。伪代码如下:
class Father{};
class Son : public Father{};
Father *pf = new Father();
Son *ps = new Son();
ps = static_cast<Son *>(pf); // 这是父类转子类,反过来子类转父类也可以
pf = static_cast<Father *>ps; // 也是对的
如上文所述,也可以用在执行类型定义的显示的转换,以及基础类型间的标准转换,伪代码如下:
double d = 3.14;
int i;
i = static_cast<int>(d);
4.dynamic_cast
直译过来就是:动态_转换,与上一步比,他只用于对象的指针与引用。
应用场景:与上一者比较,两者最主要的区别(不是唯一的区别),就是static_cast,执行时在编译期,针对的是类,而dynamic_cast,在程序运行时,针对的是对象。
好处是,dynamic_cast会检查操作是否有效,它会检查转换是否返回了一个有效的完整对象,如果不是返回值为NULL,此时被赋值的指针就被置为了NULL.
伪代码如下:
class Father{virtual func(){}};
class Son:public Father{};
Father *pf1 = new Son();
Father *pf2 = new Father();
Son *ps1 = dynamic_cast<Son *>(pf1); // 可行的
Son *ps2 = dynamic_cast<Son *>(pf2); // 失败,返回的是NULL
5. const_cast
工程应用上,很少用。这个转换类型是操作const属性的。
class Cc{};
const Cc *a = new Cc;
Cc *b = const_cast<Cc *>(a);
大概就这样,其他几种转换操作符都不能修改一个对象的常量性。