type_cast
static_cast
static_cast在功能上基本上与C风格的类型转换一样强大,含义也一样。它也有功能上限制。
例如,不能用static_cast象用C风格的类型转换一样把struct转换成int类型或者把double类型转换成指针类型,
另外,static_cast不能从表达式中去除const属性,因为另一个新的类型转换操作符const_cast有这样的功能。
const_cast
const_cast用于类型转换掉表达式的const或volatileness属性。
通过使用const_cast,向人们和编译器强调通过类型转换想做的只是改变一些东西的constness或者 volatileness属性。
这个含义被编译器所约束。如果试图使用const_cast来完成修改constness 或者volatileness属性之外的事情,类型转换将被拒绝。
到目前为止,const_cast最普通的用途就是转换掉对象的const属性。
dynamic_cast
它被用于安全地沿着类的继承关系向下进行类型转换,把指向基类的指针或引用转换成指向其派生类或其兄弟类的指针或引用。
失败的转换将返回空指针(当对指针进行类型转换时)或者抛出异常(当对引用进行类型转换时)。
它不能被用于缺乏虚函数的类型上。
class
Base
{
public:
virtual ~Base(){}
} ;
class Derived: public Base
{
} ;
void TestCast(Derived * p)
{
if(NULL == p)
cout<<"null"<<endl;
else
cout<<"pointer"<<endl;
}
Base * pBase = new Derived();
TestCast(dynamic_cast < Derived *> (pBase)); // 输出pointer
Base * pBase1 = new Base();
TestCast(dynamic_cast < Derived *> (pBase1)); // 输出null
{
public:
virtual ~Base(){}
} ;
class Derived: public Base
{
} ;
void TestCast(Derived * p)
{
if(NULL == p)
cout<<"null"<<endl;
else
cout<<"pointer"<<endl;
}
Base * pBase = new Derived();
TestCast(dynamic_cast < Derived *> (pBase)); // 输出pointer
Base * pBase1 = new Base();
TestCast(dynamic_cast < Derived *> (pBase1)); // 输出null
Base
*
pBase
=
new
Base();
try
{
Base &r = dynamic_cast<Derived&>(*pBase);
}
catch (exception & e)
{
cout<<e.what()<<endl; //输出 Bad dynamic_cast!
}
try
{
Base &r = dynamic_cast<Derived&>(*pBase);
}
catch (exception & e)
{
cout<<e.what()<<endl; //输出 Bad dynamic_cast!
}
reinterpret_cast
最普通的用途就是在函数指针类型之间进行转换。
int
doSomething()
{
cout<<"do something"<<endl;
return 0;
}
typedef void ( * FuncPtr)();
FuncPtr funcPtrArray = NULL;
// funcPtrArray = &doSomething; // 错误!类型不匹配
funcPtrArray = reinterpret_cast < FuncPtr > (doSomething);
funcPtrArray(); // 输出 do something
{
cout<<"do something"<<endl;
return 0;
}
typedef void ( * FuncPtr)();
FuncPtr funcPtrArray = NULL;
// funcPtrArray = &doSomething; // 错误!类型不匹配
funcPtrArray = reinterpret_cast < FuncPtr > (doSomething);
funcPtrArray(); // 输出 do something
reinterpret_cast仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换。
只能转换指针或者引用,值类型不行。
float
f
=
1
;
int i = static_cast < int > (f);
cout << i << endl; // 输出1
int ei = reinterpret_cast < int &> (f); // 引用
cout << ei << endl; // 输出1065353216
int fi = * reinterpret_cast < int *> ( & f); // 指针
cout << fi << endl; // 输出1065353216
int vi = reinterpret_cast < int > (f); // error
int i = static_cast < int > (f);
cout << i << endl; // 输出1
int ei = reinterpret_cast < int &> (f); // 引用
cout << ei << endl; // 输出1065353216
int fi = * reinterpret_cast < int *> ( & f); // 指针
cout << fi << endl; // 输出1065353216
int vi = reinterpret_cast < int > (f); // error