您的位置:首页 > 编程语言 > C语言/C++

C++的四种强制类型转换

2014-05-16 18:11 337 查看
一直以来,Coding时沿袭了在C语言中编程的习惯,在对不同类型数据作转换时,也按照C语言的处理方法,如下:

在C语言中,在进行自动类型转换的时候,如果原来的数是无符号数,那么在扩展的时候,高位填充的是0;如果是有符号数,那么高位填充的时符号位!这一点有点类似于“>>”操作符,当无符号数右移的时候,高位填充的是0;有符号数右移的时候,高位填充的是符号位。

C语言的类型转换分为:自动类型转换(编译器完成,隐式)和强制类型转换(自己显示去做的)。

(1)自动类型转换

赋值(=右边转成=左边的);混合运算(原则:就高不就低);函数返回值的类型转换 int  fun { double d=1.21; return d; }

       高        double    ←←    float
        ↑            ↑             
        ↑           long     

        ↑            ↑

        ↑          unsigned

        ↑            ↑

       低           int       ←←    char,short

             自动转换顺序表

(2)强制类型转换

强制将参与运算的变量或常量转换成希望出现的值。

eg:  (double)(3+2), (int)(a+b) , ( int)(3.1415926) ;

今天了解到,在C++中,除了使用C语言的类型转换方式,它还提供了用于强制类型的显示转换的四种方法,相较于C语言,它可以提供更好的强制转换过程,使程序员的意图更为明确。

与C语言 TYPEA var1=(TYPEB) var2;的形式不同,C++提供的强制类型转换的格式为:

                 TYPEA var1=强制转换类型符<TYPEB> var2;

强制转换类型符有:reinterpret_cast,static_cast,dynamic_cast和const_cast四种。以下将对其进行具体的说明和举例,并对四者进行区分:

(1)重新解释类型转换  reinterpret_cast:

      语法:   returnvalue=reinterpret_cast<casting_value>;

       它修改了操作数类型,但仅仅是重新解释了对象的比特模型而没有进行二进制转换。

      从语法上看,这个操作符仅用于指针类型的转换(返回值是指针)。它用来将一个类型指针转换为另一个类型指针,它只需在编译时重新解释指针的类型。这个操作符基本不考虑转换类型之间是否是相关的。因此往往不安全,应尽量少使用。关于reinterpret_cast的本质,http://blog.csdn.net/u013700658/article/details/25993815 一文做的试验很好的解释了reinterpret_cast不做二进制转换的特点。

(2)静态类型转换     static_cast:

      语法:returnvalue=static_cast<casting_value>;

      它类似于C风格的强制转换。无条件转换,静态类型转换。运行时不进行安全检查。主要用于:

            【1】 基类和子类之间转换:其中子类指针转换成父类指针是安全的;但父类指针转换成子类指针是不安全的。(基类和子类之间的动态类型转换建议用dynamic_cast)

            【2】 基本数据类型转换。enum, struct, int, char, float等。static_cast不能进行无关类型(如非基类和子类)指针之间的转换。

            【3】 把空指针转换成目标类型的空指针。

            【4】 把任何类型的表达式转换成void类型。

            【5】static_cast不能去掉类型的const、volitale属性(用const_cast)。

1 int n =6;
2 double d = static_cast<double>(n); // 基本类型转换
3 int *pn =&n;
4 double *d = static_cast<double*>(&n) //无关类型指针转换,编译错误
5 void *p = static_cast<void*>(pn); //任意类型转换成void类型


(3)动态类型转换    dynamic_cast:

     有条件转换,动态类型转换,运行时类型安全检查(转换失败返回NULL):

       【1】 安全的基类和子类之间转换。

       【2】 必须要有虚函数。

       【3】 相同基类不同子类之间的交叉转换。但结果是NULL。

class BaseClass
{
      public:
         int m_iNum;
         virtualvoid foo(){}; //基类必须有虚函数。保持多态性才能使用dynamic_cast
};

class DerivedClass: public BaseClass
{
     public:
        char*m_szName[100];
        void bar(){};
};

BaseClass* pb =new DerivedClass();
DerivedClass *pd1 = static_cast<DerivedClass *>(pb); //子类->父类,静态类型转换,正确但不推荐
DerivedClass *pd2 = dynamic_cast<DerivedClass *>(pb); //子类->父类,动态类型转换,正确

BaseClass* pb2 =new BaseClass();
DerivedClass *pd21 = static_cast<DerivedClass *>(pb2); //父类->子类,静态类型转换,危险!访问子类m_szName成员越界
DerivedClass *pd22 = dynamic_cast<DerivedClass *>(pb2); //父类->子类,动态类型转换,安全的。结果是NULL


(4)去const类型转换    const_cast:

例子:   

class TryStatic
{
public:
int ts;
};

const TryStatic test;
 
//test.ts = 100;        //程序中直接修改了const类型,将导致编译错误

TryStatic &test2 = const_cast<test&>(ts);

test2.ts =100;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息