命名的强制类型转换
static_cast
形式:static_cast < type-id > ( expression )
任何具有明确意义的类型转换,只要不包括底层const(指针所指的对象是常量),都可以使用static_cast。
使用场景
1、把一个较大的算术类型赋给一个较小
2、void*转化为其他指针(前提是转换回原来的指针,否则出现未定义)
const_cast
形式:const_cast<type_id> (expression)
只能改变运算对象的底层const,也就是说只能改变表达式的常量属性,不能改变类型(常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象)
例如:
int main() { const char * n="123"; // char* =static_cast<char *> (n); 出错,static_cast 不能改变底层const // string b=const_cast<string> (n); 出错,const_cast 不能改变类型 string b=static_cast<string> (n); const string p{"abc"}; const string &q=p; const string *a=&p; string* f=const_cast<string*> (a); string& g=const_cast<string&> (q); const string *h=f; const string &j=g; }
既然把一个数据设为const就意味我们不想要去改动他,所以除非万不得已,一般都不要用const_cast修改一个常量。
reinterpret_cast
形式:reinterpret_cast<type_id> (expression)
通常为运算对象的位模式提供较低层次上的重新解释,常用于不同类型指针之间的转换。
int *ip;
char *pc=reinterpret_cast<char*>(ip); //pc所指的真实对象是int类型,虽然可以转换但是不能当做char类型使用。
dynamic_cast(RTTI)
形式:dynamic_cast<type_id> (expression)
用于将基类的指针或引用安全地转换成派生类的指针或引用。(因为涉及运行时类型检测,所以父类一定有virtual才可以用dynamic_cast)
1.子类向基类的向上转型(Up Cast)
子类向基类转换,只需要将子类的指针或引用赋给基类指针或引用即可,因而向上转换肯定能成功。
2.基类向子类的向下转型(Down Cast)
dynamic_cast是将基类的指针或引用安全的转换为子类指针或引用,dynamic_cast根据基类指针是否真正指向子类来做相应处理,因而涉及了运行时类型检测。
如果绑定到引用或者指针的对象不是目标的对象,则转换失败,指针类型返回0,引用类型抛出bad_cast异常。
1 class Base 2 { 3 public: 4 Base(int a=5488):m_int(a){} 5 virtual int Get(){return m_int;} 6 private: 7 int m_int; 8 } ; 9 10 class Derive:public Base 11 { 12 public: 13 Derive(int a=5424):n_int(a){} 14 int Get(){return n_int;} 15 private: 16 int n_int; 17 }; 18 19 int main() 20 { 21 Base *fp,f; 22 Derive *sp,s; 23 //指向基类的基类指针转换为指向子类的子类指针,转换失败 24 sp=&s; 25 fp=&f; 26 cout<<fp->Get()<<endl; 27 if(typeid(*sp)==typeid(*fp)) 28 cout<<"sp=fp"<<endl; 29 else 30 cout<<"sp!=fp"<<endl; 31 sp=dynamic_cast<Derive*>(fp); 32 if(sp) 33 cout<<sp->Get()<<" "<<endl; 34 else 35 cout<<"lose to change"<<endl; 36 37 //指向子类的基类指针转换为指向子类的子类指针,转换成功 38 sp=&s; 39 fp=&s; 40 cout<<fp->Get()<<endl; 41 42 if(typeid(*sp)==typeid(*fp)) 43 cout<<"sp=fp"<<endl; 44 else 45 cout<<"sp!=fp"<<endl; 46 sp=dynamic_cast<Derive*>(fp); 47 if(sp) 48 cout<<sp->Get()<<" "<<endl; 49 else 50 cout<<"lose to change"<<endl; 51 }
另外相关的运算符
类型转换运算符(隐式转换)
形式:operator type() const;//没有返回类型,没有参数,type需要转化成的类型,必须是类的成员运算符。
一般类型转换不应该改变原类型的内容,因而定义为const。
隐式类型转换应该少用,避免产生意外结果
显式的类型转换运算符(C++11新引入的)
explicit operator type()const;
在以下情况可以使用
1、运用强制类型转换时
2、表达式被用作条件时