多语言展示
当前在线:1959今日阅读:27今日分享:41

C++类型转换使用总结

对于C语言的松散类型转换,Stroustrop采取的措施是更严格地限制允许的类型转换,并添加4个类型转换运算符,使转换过程更规范:dynamic_cast;const_cast;static_cast;reinterpret_cast;       可以根据目的选择一个更适合的运算符,而不是使用通用的类型转换。这指出了进行类型转换的原因,并让编译器能够检查程序的行为是否与设计者想法吻合。       使用这四种类型转换运算符不需要导入其它的头文件,以及任何namespace。因为他们是运算符,地位和sizeof( )、+ 、/ 等一致。
dynamic_cast 类型转换运算符
1

dynamic_cast运算符的用途是使得能够在类层次结构中进行向上转换(属于is-a关系,这样的类型转换是安全的),而不允许其它类型转换。该运算符的语法如下:dynamic_cast (experssion)    //注意必须有这对小括号,下同

2

dynamic_cast运算符已经在前面介绍过了。总之,假设High和Low是两个类,而ph和pl类型分别为High *和Low *,则仅当Low是High的可访问基类(直接或间接)时,下面的语句才将一个High *指针赋给(转换成Low *)pl:pl = dynamic_cast ph;      否则,该语句将空指针赋给pl,即pl = NULL或pl = 0。

const_cast 类型转换运算符
1

const_cast运算符用于执行只有一种用途的类型转换,即改变为有或无const或volatile(注:volatile adj.易变的)特征,其语法为:const_cast (expression)       如果类型的其他方面也被修改,则上述类型转换将出错。也就是说,除了const或volatile特征(有或无)可以不同外,type_name和expression的类型(指数据类型)必须相同。

2

const_cast只能去除指针上的const属性,而不能去除已经定义好的变量上的const属性(如,const int counter),因为变量的存储类型一旦定义后就能不能改变。因此对除指针、数据成员指针、引用外的const类型变量使用const_cast类型转换符是非法的。const int counter = 0;int num = 12;num = const_cast (counter);   //invalid  #1//-------------------  convert 'const int *' to 'int *'  -------------------//const int * pInt = #int * iptr = const_cast (pInt);   //valid   #2//------------------- convert 'int * const' to 'int *'-------------------//int * const icptr = #iptr = const_cast (icptr);   //valid   #3//------------ convert 'const int * const' to 'const int *' ---------//const int * const cicptr = #pInt = const_cast (cicptr);   //valid   #4//---------------- convert 'int * const' to 'int *' ---------------//int * const icptr = #iptr = const_cast (icptr);   //valid   #5//----------- convert 'const int * const' to 'int *' ---------//iptr = const_cast (cicptr);     //valid   #6//-----------  #1编译错误提示      在类型‘int’上使用 const_cast 无效,因为它既不是指针,也不是引用,也不是数据成员指针。

3

假设High和Low是两个类:High bar;const High *pbar = &bar;……High * pb = const_cast(pbar);   //validconst Low *pl = const_cast(pbar);   //invalid        第一个类型转换使得*pb成为一个可用于修改bar对象值的指针,它删除const标签。第二个类型转换是非法的,因为他同时尝试将类型从const High * 改为const Low *。        提供该运算符的原因是有时候可能需要这样的一个值,它在大多数情况下是常量,而有时候又是可以修改的。在这种情况下,可以将这个值声明为const,并在需要的时候修改它的时候使用const_cast。

4

补充:volatile 关键字作用:volatile 屏蔽系统对变量可能的优化;volatitle 这个关键字表述的问题一般都比较底层。应用场景:1) 并行设备的硬件寄存器(如:状态寄存器)几乎所有的 GPIO 的描述都包含这个关键字;#define inp(port) (((volatile byte ) (port)))2) 一个中断服务子程序中会访问到的非自动变量3) 多线程应用中被几个任务共享的变量

5

const_cast类型转换举例:#include using std::cout;using std::endl;void change(const int * pt, int n ){    int *pc;    pc = const_cast(pt);    *pc += n;}//int main( ){    int  pop1 = 38383;    const int pop2 = 2000;    cout << 'pop1, pop2: << pop1 << ',' << pop2 << endl;    change(&pop1, -103);    change(&pop2, -103);    cout << 'pop1, pop2:' << pop1 << ',' << pop2 << endl;}//----------------- Out put: -----------------//pop1,pop2:38383,2000pop1,pop2:38280,2000

static_cast 类型转换运算符
1

static_cast运算符的语法与其他类型转换运算符相同:           static_cast (expression)      仅当type-name可被隐式转换为expression所属的类型或expression可被隐式转换为type-name所属的类型时,上述转换才是合法的,否则将出错。假设High是Low的基类,而Pond是一个无关的类,则从High到Low的转换、从Low到High的转换都是合法的,而从Low到Pond的转换是不允许的:    High bar;    Low  blow;    ...    High *pb = static_cast (&blow);   //valid upcast    Low  *pl = static_cast (&bar);        //valid downcast    Pond *pmer = static_cast (&blow);  //invalid, Pond unrelated       第一种转换是合法的,因为向上转型可以显示地进行。       第二种转换是从基类指针到派生类指针,在不进行显示类型转换的情况下,将无法进行。但由于无须进行类型转换,便可以进行另一个方向的类型转换。因此使用static_cast来进行向下转换是合法的。       第三种转换是无法满足前面加粗文字描述的规则,所以是非法的转换。

2

同样,由于无须进行类型转换,枚举值就可以被转换成为整型,所以可以用static_cast将整型转换为枚举值。可以使用static_cast将double转换为int、将float转换为long以及其它各种数值转换。

reinterpret_cast 类型转换运算符
1

interpret    [美]ɪnˈtɜ:rprɪt        vt.解释;reinterpret    [美]ˌri:ɪnˈtɜ:rprɪt         vt.重新解释       摆上两个单词是想表达reinterpret_cast类型转换运算符的作用,其作用就如其名——将一种类型重新转换为另一种类型(两种类型甚至毫无关系)。       reinterpret_cast运算符用于天生危险的类型转换。它不允许删除const,但会执行其它令人生厌的操作。有时候程序员必须做一些依赖实现的、令人生厌的操作,使用reinterpret_cast运算符可以简化对这种行为的跟踪工作。该运算符的语法与另外3个相同:              reinterpret_cast (expression);

2

下面是一个使用示例:struct dat{      short a;      short b;};long value = 0xA224B118;  // long即long int简写dat  *pd = reinterpret_cast (&value);cout << std::hex << pd->a;   //display first 2 bytes of value       通常,这样转换适用于依赖实现的底层编程技术,是不可移植的。例如,不同的系统存储多字节整型时,可能以不同的顺序存储其中的字节。

3

然而,reinterpret_cast运算符并不支持所有的类型转换。例如,可以将指针类型转换为足以存储指针表示的整型,但不能将指针转换为更小的整型或浮点型。另一个限制是,不能将函数指针转换为数据指针,反之亦然。

小结

在C++中,普通类型转换也受到限制。基本上,可以执行其它类型转换可以执行的操作,加上一些组合,如static_cast或reinterpret_cast后跟const_cast,但不能执行其它转换。因此,线面的类型转换在C语言中是允许的,但在C++中通常不允许,因为对于大多数C++实现,char类型都太小,不能存储指针:            char ch = (char) &d;      这些限制是合理的,如果您觉得这种限制难以忍受,可以使用C语言。

推荐信息