强制类型转换

命名的强制类型转换

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、表达式被用作条件时

posted on 2017-06-06 16:39  kiplove  阅读(394)  评论(0编辑  收藏  举报

导航