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;
}

相关资料参考网址:

http://baike.baidu.com/view/1745213.htm

http://read.newbooks.com.cn/info/161950.html

(转载时请注明作者和出处。未经许可,请勿用于商业用途)
更多文章请访问我的Blog: http://www.cnblogs.com/alexqdh

C++四种强制转换的更多相关文章

  1. C++四种强制类型转换详解

    什么是类型转换? 类型转换的含义是通过改变一个变量的类型为别的类型从而改变该变量的表示方式.为了类型转换一个简单对象为另一个对象你会使用传统的类型转换操作符. C与C++的类型转换 //C中: //复 ...

  2. 四种强制类型转换的总结(const_cast、static_cast、dynamic_cast、reinterpreter_cast)

    四种强制类型转换的总结(const_cast.static_cast.dynamic_cast.reinterpreter_cast) 转载 2011年10月03日 23:59:05 标签: stru ...

  3. C++中的关键字用法--- 四种强制类型转换的总结

    四种强制类型转换的总结(const_cast.static_cast.dynamic_cast.reinterpreter_cast 1. C风格的强制类型转换(Type Cast)很简单,不管什么类 ...

  4. [转载]C++中四种强制类型转换方式

    C++中四种强制类型转换方式 原文地址:http://www.cnblogs.com/home123/p/6763967.html 类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单( ...

  5. 【C++】 四种强制类型转换(static_cast 与 dynamic_cast 的区别!)

    强制类型转换 1. static_cast 2. dynamic_cast 3. const_cast 4. reinterpret_cast 5. 为什么要需要四种类型转换? 1. static_c ...

  6. [C++][操作符]四种显示转换操作符

    整理了C++ Primer中提到的四种显示转换,用思维导图写出来,是不是很清晰O(∩_∩)O.

  7. c++四种强制类型转化

    c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast C++ 类型转换(C风格的强制转换): (1)将浮点型数据赋值给整型变 ...

  8. C++的四种强制转型形式:

    C++同时提供了四种新的强制转型形式(通常称为新风格的或C++风格的强制转型): const_cast(expression)dynamic_cast(expression)reinterpret_c ...

  9. C++ 四种强制类型转换

    来自csdn:http://blog.csdn.net/hgl868/article/details/46619399 C风格的强制类转换(Type Cast)很简单,不管什么类型的转换统统是: TY ...

随机推荐

  1. 20165210 《网络对抗技术》week1 exp0 kali安装与配置

    20165210 <网络对抗技术>week1 exp0 kali安装与配置 1. 安装过程: 从kali官网上下载如下图所示: 下载完成后打开VMware 点击创建新的虚拟机 弹出新虚拟机 ...

  2. 【dlbook】优化

    [神经网络优化的挑战] 一.病态: 虽然学习率很小,而且梯度大,但是由于Hessian阵的病态,二次项比一次项还要大,梯度下降事实上并不一定能下降,反而有可能上升.因此需要将学习率调低. 表现:梯度很 ...

  3. 在IE中MVC控制器中返回JSON格式的数据时提示下载

    最近做项目时,视图中用jquery.form.js异步提交表单时,接收的是JSON格式的数据,但是奇怪的是在IE中提示下载文件,其他浏览器中一切正常,下载后,里面的内容就是在控制器中返回的数据.代码如 ...

  4. LXC、LXD、Docker的区别与联系(by quqi99)

    版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 ) 容器 namespace技术用来进行做进程间的隔 ...

  5. Java 7 新特性try-with-resources语句

    1.什么是try-with-resources语句 try-with-resources 语句是一个声明一个或多个资源的 try 语句.一个资源作为一个对象,必须在程序结束之后随之关闭. try-wi ...

  6. java入门学习(2)—基本数据类型

    1.变量:定义变量:[数据类型] 变量名 = 赋值(这样定义的变量一般属于局部变量,放置在栈内存中): 2.标识符:可以有字母(可以使任意文字),数字,下划线,$等组成:但是不能以数字开头,不能是保留 ...

  7. 锐捷S2126交换机端口限速

    一.对于S21的进入(上行)的数据的限速,可以用Qos做到. ip access-list extended acl_1                配置ACLpermit ip 172.16.41 ...

  8. Android学习笔记之Android Studio添加新的Activity

    1.创建Android项目工程:AndroidTest 创建过程可参考网上诸多教程. 2.添加新的Activity,步骤如下 a. 在layout文件夹上右键,New-Activity-相应Activ ...

  9. Jmeter查看结果树

    取样结果: Thread Name: test 1-2                                                     线程名称:测试1 - 2Sample S ...

  10. bzoj 4827 礼物

    bzoj 4827 礼物 可以看做将其中一个数列(假定为 \(a\) )都加上 \(c\) , \(c\) 可以为负数.易知这里 \(-m\leq c\leq m\). 记要求的答案为 \(ans\) ...