C风格的强制类型转换(Type Cast)很简单,无论什么类型的转换通通是:TYPE b = (TYPE)a,可是c 风格的类型转换有很多的缺点,有的时候用c风格的转换是不合适的,由于它能够在任意类型之间转换,好比你能够把一个指向const对象的指针转换成指向非 const对象的指针,把一个指向基类对象的指针转换成指向一个派生类对象的指针,这两种转换之间的差异是巨大的,可是传统的c语言风格的类型转换没有区 分这些。还有一个缺点就是,c风格的转换不容易查找,他由一个括号加上一个标识符组成,而这样的东西在c++程序里一大堆。因此c++为了克服这些缺点,引进了4种类型转换操做符(C++风格的强制转换其余的好处是,它们能更清晰的代表它们要干什么。程序员只要扫一眼这样的代码,就能当即知道一个强制转换的目的。):ios
一、static_cast:能够实现C++中内置基本数据类型之间的相互转换,enum、struct、 int、char、float等。它不能进行无关类型(如非基类和子类)指针之间的转换。c++
int c=static_cast<int>(7.987);程序员
若是涉及到类的话,static_cast只能在有相互联系的类型中进行相互转换,不必定包含虚函数。安全
class A {}; class B:public A {}; class C {}; int main() { A* a=new A; B* b; C* c; b=static_cast<B>(a); // 编译不会报错, B类继承A类 c=static_cast<B>(a); // 编译报错, C类与A类没有任何关系 return 1; }
二、const_cast: const_cast操做不能在不一样的种类间转换。相反,它仅仅把一个它做用的表达式转换成常量。它可使一个原本不是const类型的数据转换成const类型的,或者把const属性去掉。
三、reinterpret_cast: (interpret是解释的意思,reinterpret即为从新解释,此标识符的意思即为数据的二进制形式从新解释,可是不改变其值。)有着和C风格的强制转换一样的能力。它能够转化任何内置的数据类型为其余任何的数据类型,也能够转化任何指针类型为其余的类型。它甚至能够转化内置的数据类型为指针,无须考虑类型安全或者常量的情形。不到万不得已绝对不用。
四、dynamic_cast:
(1)其余三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。
(2)不能用于内置的基本数据类型的强制转换。
(3)dynamic_cast转换若是成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。
(4)使用dynamic_cast进行转换的,基类中必定要有虚函数,不然编译不经过。
须要检测有虚函数的缘由:类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的状况,此时转换才有意义。
这是因为运行时类型检查须要运行时类型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念,详细可见<Inside c++ object model>)中,
只有定义了虚函数的类才有虚函数表。
(5) 在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是同样的。在进行下行转换 时,dynamic_cast具备类型检查的功能,比 static_cast更安全。向上转换即为指向子类对象的向下转换,即将父类指针转化子类指针。向下转换的成功与否还与将要转换的类型有关,即要转换的指针指向的对象的实际类型与转换之后的对象类型必定要相同,不然转换失败。ide
例如:函数
#include<iostream> #include<cstring> using namespace std; class A { public: virtual void f() { cout<<"hello"<<endl; }; }; class B:public A { public: void f() { cout<<"hello2"<<endl; }; }; class C { void pp() { return; } }; int fun() { return 1; } int main() { A* a1=new B;//a1是A类型的指针指向一个B类型的对象 A* a2=new A;//a2是A类型的指针指向一个A类型的对象 B* b; C* c; b=dynamic_cast<B*>(a1);//结果为not null,向下转换成功,a1以前指向的就是B类型的对象,因此能够转换成B类型的指针。 if(b==NULL) { cout<<"null"<<endl; } else { cout<<"not null"<<endl; } b=dynamic_cast<B*>(a2);//结果为null,向下转换失败 if(b==NULL) { cout<<"null"<<endl; } else { cout<<"not null"<<endl; } c=dynamic_cast<C*>(a);//结果为null,向下转换失败 if(c==NULL) { cout<<"null"<<endl; } else { cout<<"not null"<<endl; } delete(a); return 0; }
同时能够参考下:C++开发必看 四种强制类型转换的总结spa