C++类型转换使用总结

2026-03-06 01:33:42

1、      dynamic_cast运算符的用途是使得能够在类层次结构中进行向上转换(属于is-a关系,这样的类型转换是安全的),而不允许其它类型转换。

该运算符的语法如下:

dynamic_cast <type-name> (experssion)    //注意必须有这对小括号,下同

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

pl = dynamic_cast<Low *> ph;

      否则,该语句将空指针赋给pl,即pl = NULL或pl = 0。

1、       const_cast运算符用于执行只有一种用途的类型转换,即改变为有或无const或volatile(注:volatile adj.易变的)特征,其语法为:

const_cast <type_name> (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<int> (counter);   //invalid  #1

//-------------------  convert 'const int *' to 'int *'  -------------------//

const int * pInt = &num;

int * iptr = const_cast<int *> (pInt);   //valid   #2

//------------------- convert 'int * const' to 'int *'-------------------//

int * const icptr = &num;

iptr = const_cast<int *> (icptr);   //valid   #3

//------------ convert 'const int * const' to 'const int *' ---------//

const int * const cicptr = &num;

pInt = const_cast<const int *> (cicptr);   //valid   #4

//---------------- convert 'int * const' to 'int *' ---------------//

int * const icptr = &num;

iptr = const_cast<int *> (icptr);   //valid   #5

//----------- convert 'const int * const' to 'int *' ---------//

iptr = const_cast<int *> (cicptr);     //valid   #6

//-----------  #1编译错误提示

      在类型‘int’上使用 const_cast 无效,因为它既不是指针,也不是引用,也不是数据成员指针。

3、假设High和Low是两个类:

High bar;

const High *pbar = &bar;

……

High * pb = const_cast<High *>(pbar);   //valid

const Low *pl = const_cast<const Low *>(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 <iostream>

using std::cout;

using std::endl;

void change(const int * pt, int n )

{

    int *pc;

    pc = const_cast<int *>(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,2000

pop1,pop2:38280,2000

1、     static_cast运算符的语法与其他类型转换运算符相同:

           static_cast<type-name> (expression)

      仅当type-name可被隐式转换为expression所属的类型expression可被隐式转换为type-name所属的类型时,上述转换才是合法的,否则将出错。假设High是Low的基类,而Pond是一个无关的类,则从High到Low的转换、从Low到High的转换都是合法的,而从Low到Pond的转换是不允许的:

    High bar;

    Low  blow;

    ...

    High *pb = static_cast<High *> (&blow);   //valid upcast

    Low  *pl = static_cast<Low *> (&bar);        //valid downcast

    Pond *pmer = static_cast<Pond *> (&blow);  //invalid, Pond unrelated

       第一种转换是合法的,因为向上转型可以显示地进行。

       第二种转换是从基类指针到派生类指针,在不进行显示类型转换的情况下,将无法进行。但由于无须进行类型转换,便可以进行另一个方向的类型转换。因此使用static_cast来进行向下转换是合法的。

       第三种转换是无法满足前面加粗文字描述的规则,所以是非法的转换。

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

1、interpret    [美]ɪnˈtɜ:rprɪt        vt.解释;

reinterpret    [美]ˌri:ɪnˈtɜ:rprɪt         vt.重新解释

       摆上两个单词是想表达reinterpret_cast类型转换运算符的作用,其作用就如其名——将一种类型重新转换为另一种类型(两种类型甚至毫无关系)。

       reinterpret_cast运算符用于天生危险的类型转换。它不允许删除const,但会执行其它令人生厌的操作。有时候程序员必须做一些依赖实现的、令人生厌的操作,使用reinterpret_cast运算符可以简化对这种行为的跟踪工作。该运算符的语法与另外3个相同:

              reinterpret_cast<type-name> (expression);    

2、下面是一个使用示例:

struct dat

{

      short a;

      short b;

};

long value = 0xA224B118;  // long即long int简写

dat  *pd = reinterpret_cast<dat *> (&value);

cout << std::hex << pd->a;   //display first 2 bytes of value

       通常,这样转换适用于依赖实现的底层编程技术,是不可移植的。例如,不同的系统存储多字节整型时,可能以不同的顺序存储其中的字节。

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

1、       在C++中,普通类型转换也受到限制。基本上,可以执行其它类型转换可以执行的操作,加上一些组合,如static_cast或reinterpret_cast后跟const_cast,但不能执行其它转换。因此,线面的类型转换在C语言中是允许的,但在C++中通常不允许,因为对于大多数C++实现,char类型都太小,不能存储指针:

            char ch = (char) &d;

      这些限制是合理的,如果您觉得这种限制难以忍受,可以使用C语言。

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢