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

C++的四种强制类型转换,所以C++不是类型安全的。分别为:static_cast , dynamic_cast , const_cast , reinterpret_cast

为什么使用C风格的强制转换可以把想要的任何东西转换成合乎心意的类型。那为什么还需要一个新的C++类型的强制转换呢?

新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同种类的强制转换。C++中风格是 static_cast<type>(content)。C++风格的强制转换其他的好处是,它们能更清晰的表明它们要干什么。程序员只要扫 一眼这样的代码,就能立即知道一个强制转换的目的。

四种转换的区别:

static_cast:可以实现C++中内置基本数据类型之间的相互转换。

?
1
int c= static_cast < int >(7.987);

如果涉及到类的话,static_cast只能在有相互联系的类型中进行相互转换,不一定包含虚函数

?
class A
{};
class B: public A
{};
class C
{};
 
int main()
{
     A* a= new A;
     B* b;
     C* c;
     b= static_cast <B>(a);  // 编译不会报错, B类继承A类
     c= static_cast <B>(a);  // 编译报错, C类与A类没有任何关系
     return 1;
}

const_cast: const_cast操作不能在不同的种类间转换。相反,它仅仅把一个它作用的表达式转换成常量。它可以使一个本来不是const类型的数据转换成const类型的,或者把const属性去掉。

reinterpret_cast: 有着和C风格的强制转换同样的能力。它可以转化任何内置的数据类型为其他任何的数据类型,也可以转化任何指针类型为其他的类型。它甚至可以转化内置的数据类型为指针,无须考虑类型安全或者常量的情形。不到万不得已绝对不用。

dynamic_cast: 

(1)其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。

(2)不能用于内置的基本数据类型的强制转换。

(3)dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。

(4)使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。

        B中需要检测有虚函数的原因:类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的情况,此时转换才有意义。

        这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念,详细可见<Inside c++ object model>)中,

        只有定义了虚函数的类才有虚函数表。

 (5)在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的 效果是一样的。在进行下行转换时,dynamic_cast具有类型检查的功能,比               static_cast更安全。向上转换即为指向子类对象的向下转换,即将父类指针转化子类指针。向下转换的成功与否还与将要转换的类型有关,即要转换的 指针指向的对象的实际类型与转换以后的对象类型一定要相同,否则转换失败。

参考例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include<iostream>
#include<cstring>
using namespace std;
class A
{
    public :
    virtual void f()
    {
        cout<< "hello" <<endl;
        };
};
 
class B: public A
{
     public :
     void f()
     {
         cout<< "hello2" <<endl;
         };
 
};
 
class C
{
   void pp()
   {
       return ;
   }
};
 
int fun()
{
     return 1;
}
int main()
{
     A* a1= new B; //a1是A类型的指针指向一个B类型的对象
     A* a2= new A; //a2是A类型的指针指向一个A类型的对象
     B* b;
     C* c;
     b= dynamic_cast <B*>(a1); //结果为not null,向下转换成功,a1之前指向的就是B类型的对象,所以可以转换成B类型的指针。
     if (b==NULL)
     {
         cout<< "null" <<endl;
     }
     else
     {
         cout<< "not null" <<endl;
     }
     b= dynamic_cast <B*>(a2); //结果为null,向下转换失败
     if (b==NULL)
     {
         cout<< "null" <<endl;
     }
     else
     {
         cout<< "not null" <<endl;
     }
     c= dynamic_cast <C*>(a); //结果为null,向下转换失败
     if (c==NULL)
     {
         cout<< "null" <<endl;
     }
     else
     {
         cout<< "not null" <<endl;
     }
     delete (a);
     return 0;
}

你可能感兴趣的:(类型转换)