1、const_cast
// const_cast #include <iostream> using namespace std; void print (char * str) { cout << str << endl; } int main () { const char * c = "sample text"; print ( const_cast<char *> (c) ); return 0; }
2、dynamic_cast
只能够用在指向类的指针或者引用上(或者void*)。这种转换的目的是确保目标指针类型所指向的是一个有效且完整的对象。
同隐式转换一样,这种转换允许upcast(从派生类向基类的转换)。但dynamic_cast 也能downcast(从基类向派生类的转换)当且仅当转过去的指针所指向的目标对象有效且完整。
// dynamic_cast #include <iostream> #include <exception> using namespace std; class CBase { virtual void dummy() {} }; class CDerived: public CBase { int a; }; int main () { try { CBase * pba = new CDerived; CBase * pbb = new CBase; CDerived * pd; pd = dynamic_cast<CDerived*>(pba); if (pd==0) cout << "Null pointer on first type-cast" << endl; pd = dynamic_cast<CDerived*>(pbb); if (pd==0) cout << "Null pointer on second type-cast" << endl; } catch (exception& e) {cout << "Exception: " << e.what();} return 0; }
3、static_cast
class CBase {}; class CDerived: public CBase {}; CBase * a = new CBase; CDerived * b = static_cast<CDerived*>(a);
double d=3.14159265; int i = static_cast<int>(d);
能够完成任意指针类型向任意指针类型的转换,即使它们毫无关联。该转换的操作结果是出现一份完全相同的二进制复制品,既不会有指向内容的检查,也不会有指针本身类型的检查。
reinterpret_cast也能够完成指针向整数的转换。不过该整数的类型取决于平台。唯一的保证是该整数的类型能够容纳下指针的值以及能够再次被转换成一个有效的指针。
基本上reinterpret_cast能做但static_cast不能做的转换大多都是一些基于重新解释二进制的底层操作,因此会导致代码限定于特定的平台进而导致差移植性。
class A {}; class B {}; A * a = new A; B * b = reinterpret_cast<B*>(a);
①reinterpret_cast:类型转换函数将一个类型的指针转换为另一个类型的指针。这种转换不需要修改指针变量值数据存放格式,只需在编译时重新编译解释指针的类型即可。
double d = 9.3; double *pd = &d; int *pi = reinterpret_cast<int*>(pd); |
但是不能用于非指针类型的转换。同隐式转换一样,reinterpret_cast也不能将一个const指针转换为void*指针。
②const_cast:用于去除指针变量的常量属性,将它转换为一个对应指针类型的普通变量。也可以将一个非常量的指针变量转换为一个常指针变量,在编译期间做出类型更改。
const int* pci = 0; int* pj = const_cast<int*>(pci); |
③static_cast:用于基本类型之间和具有继承关系的类型之间的转换,这种转换一般会更改变量的内部表示方式。
class Base(); class Derived :public Base {} Derived d; Base d = static_cast<Base>(d); |
可将继承类对象转换为基类对象。但是反过来不行。
【注意】基类指针转换为继承类指针,在一定的危害性。
④dynamic_cast:与static_cast相对,是动态dynamic_cast转换。这种转换是在运行时进行转换分析的,并非在编译时进行。只能在继承类对象的指针之间或引用之间进行类型转换。进行转换时,会根据当前(RTTI)判断类型对象之间的转换是否合法。dynamic_cast转换失败,是通过是否为null指针检测;引用转换失败,抛出bad_cast异常。
将继承类指针或引用转换为基类指针或引用可以,反过来一般不行;但是如果基类中有虚函数也可以,也就是说被转换的类具有虚函数的对象指针时,编译也通过。
class Base(); class Derived :public Base {} Derived *pd = new Derived; Base *d = dynamic_cast<Base*>(pd); |