static_cast与dynamic_cast转换

C语言中两种类型转换

隐式转换和显式转换

隐式转换:不同数据类型之间赋值和运算,函数调用传递参数,由编译器完成。

char ch;

int i = ch;

显示转换:在类型前增加:(Type)变量,对变量进行的转换。用户显式增加。

char *pc = (char*)pb;

void *ps = (void*)pa;

C++中类型转换

通过这两种方式,C语言中大部分的类型转换都可以顺利进行。

至于能不能进行转换,转换后的结果如何,编译器不管,需要用户自己去控制。

C++继承了C中的隐式和显式转换的方式。但这种转换并不是安全和严格的,加上C++本身对象模型的复杂性,C++(C++是强类型语言)增加了四个显示转换的关键字:static_cast,dynamic_cast,const_static,reinterpret_cast。

static_cast

用于基本的数据类型转换(char,int)及指针之间的转换

test_enum type = test_enum_1;

char a ;

int b = static_cast<int>(a);

char c = static_cast<char>(b);

type = static_cast<test_enum>(b);

char* pa = NULL;

int *pb = (int*)pa;

//int *pb = static_cast<int*>(pa);        //error

//pa = static_cast<char*>(pb)           //error

char *pc = (char*)pb;

//char *pc = static_cast<char*>(pb);    //error

void *p = static_cast<void*>(pa);

pb = static_cast<int*>(p);

pc = static_cast<char*>(p);

类层次中基类与子类成员函数指针的转换

class A

{

public:

void set(){}

};

class B:public A

{

public:

void set(){}

};

typedef void (A::*PS_MFunc)();      // 指向类A的成员函数指针

PS_MFunc func = &A::set;

func = static_cast<PS_MFunc>(&B::set); // 基类指向子类成员函数指针,必须进行转换

类层次结构中基类与子类指针或引用之间的转换

上行转换:子类指针或引用转换成基类表示——安全;

下行转换:基类指针或引用转换成子类表示——危险(没有动态类型检查)。

class A

{

};

class B:public A

{

};

class C:public A

{

};

class D

{

};

A objA;

B objB;

A* pObjA = new A();

B* pObjB = new B();

C* pObjC = new C();

D* pObjD = new D();

objA = static_cast<A&>(objB);     //转换为基类引用

objA = static_cast<A>(objB);

objB = static_cast<B>(objA);      //error 不能进行转换

pObjA = pObjB;                    //right 基类指针指向子类对象

//objB = objA;                      //error 子类指针指向基类对象

pObjA = static_cast<A*>(pObjB);   //right 基类指针指向子类

pObjB = static_cast<B*>(pObjA);   //强制转换 OK 基类到子类

//pObjC = static_cast<C*>(pObjB);   //error 继承于统一类的派生指针之间转换

//pObjD = static_cast<D*>(pObjC);   //error 两个无关联之间转换

dynamic_cast

继承关系的类指针对象或引用之间转换

class A

{

};

class B:public A

{

};

class C:public A

{

};

class D

{

};

A objA;

B objB;

A* pObjA = new A();

B* pObjB = new B();

C* pObjC = new C();

D* pObjD = new D();

//objA = dynamic_cast<A>(objB);         //error 非引用

objA = dynamic_cast<A&>(objB);

//objB = dynamic_cast<B&>(objA);      //error A 不是多态类型不能转换 若有虚函数则可以进行转换

pObjA = dynamic_cast<A*>(pObjB);

//pObjB = dynamic_cast<B*>(pObjA);    //error A 继承关系 不是多态类型不能转换

//pObjB = dynamic_cast<B*>(pObjC);    //error C 兄弟关系 不是多态类型不能转换

//pObjB = dynamic_cast<B*>(pObjD);    //error D 没有关系 不是多态类型不能转换

包含有虚函数之间对象指针的转换

class A

{

Public:

Virtual ~A(){}

};

class B:public A

{

};

class C:public A

{

};

class D

{

Public:

Virtual ~D(){}

};

pObjB = dynamic_cast<B*>(pObjA);    // worning 继承关系 父类具有虚函数 多态

pObjB = dynamic_cast<B*>(pObjD);    //worning 没有关系 D是多态类型可以转换

//以上结果:pObjB == NULL 此处会发生一个运行时错误

也就是说除了基类指针指向子类对象,可以没有虚函数外,其它要进行dynamic_cast转换必须具有虚函数才行。

那这是为什么呢?下面继续>

dynam_cast转换的安全性

dynamic_cast是动态转换,只有在基类指针转换为子类指针时才有意义。子类指针转换为基类指针本来就是可以的:基类指针指向子类对象OK。

但是基类指针转换为子类指针,并不是每一次都有效:只有基类指针本身指向的是一个派生类的对象,然后将此基类指针转换为对应的派生类指针才是有效的。这种情况在表面上是无法判定的。此时dynamic就发挥了作用。

情况1:static_cast转换

class A

{

};

class B:public A

{

public:

int m;         //B 成员

};

A* pObjA = new A();

B* pObjB  = NULL;

pObjB = static_cast<B*>(pObjA);   //基类指针转化为子类指针 成功转换

pObjB->m = 10;                 //实际中pObj所指向的对象 是A类对象

//上面会发生什么呢,在VC6.0中正常运行。。。?

//如果:

pObjB = dynamic_cast<B*>(pObjA); //error 基类A没有虚函数,不构成多态。

情况2:dynamic_cast转换

class A

{

public:

virtual ~A(){}         //虚函数,多态

};

class B:public A

{

public:

int m;

};

A* pObjA = new A();

B* pObjB  = NULL;

pObjB = dynamic_cast<B*>(pObjA);  //编译通过

//实际运行结果:pObjB == NULL   // dynamic_cast保证转换无效,返回NULL

dynamic_cast转换不成功,则返回0。

4 虚函数对于dynamic_cast转换的作用

为何使用dynamic_cast转换类指针时,需要虚函数呢。

Dynamic_cast转换是在运行时进行转换,运行时转换就需要知道类对象的信息(继承关系等)。

如何在运行时获取到这个信息——虚函数表。

C++对象模型中,对象实例最前面的就是虚函数表指针,通过这个指针可以获取到该类对象的所有虚函数,包括父类的。

因为派生类会继承基类的虚函数表,所以通过这个虚函数表,我们就可以知道该类对象的父类,在转换的时候就可以用来判断对象有无继承关系。所以虚函数对于正确的基类指针转换为子类指针是非常重要的。

static_cast与dynamic_cast转换相关推荐

  1. C++的类型强制转换,static_cast,dynamic_cast,const_cast,reinterpret_cast

    1. c强制转换与c++强制转换 c语言强制类型转换主要用于基础的数据类型间的转换,语法为: (type-id)expression//转换格式1type-id(expression)//转换格式2 ...

  2. C++四种cast转换(const_cast、static_cast、dynamic_cast、reinpreter_cast)类型转换运算符

    文章目录 cast含义 C++四种类型转换符各自应用场景(简略) 1. static_cast 2. dynamic_cast 3. reinterpret_cast 4. const_cast C+ ...

  3. const_cast,dynamic_cast,reinterpret_cast,static_cast四种转换的区别

    const_cast,dynamic_cast,reinterpret_cast,static_cast四种转换的区别 一,const_cast 二,dynamic_cast 三,reinterpre ...

  4. C++中static_cast/const_cast/dynamic_cast/reinterpret_cast的区别和使用

    C风格的强制转换较简单,如将float a转换为int b,则可以这样:b = (int)a,或者b=int(a). C++类型转换分为隐式类型转换和显示类型转换. 隐式类型转换又称为标准转换,包括以 ...

  5. static_cast、dynamic_cast、const_cast和reinterpret_cast总结

    前言 这篇文章总结的是C++中的类型转换,这些小的知识点,有的时候,自己不是很注意,但是在实际开发中确实经常使用的.俗话说的好,不懂自己写的代码的程序员,不是好的程序员:如果一个程序员对于自己写的代码 ...

  6. C/C++ 之 C++强制类型转换(static_cast、dynamic_cast、const_cast、reinterpret_cast)

    文章转载自:https://www.cnblogs.com/chenyangchun/p/6795923.html .在了解这块时,发现了这篇文档,感觉写的很不错! c强制转换与c++强制转换 c 语 ...

  7. 标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast(转载)

    C 风格(C-style)强制转型如下: (T) exdivssion // cast exdivssion to be of type T 函数风格(Function-style)强制转型使用这样的 ...

  8. static_cast、dynamic_cast、reinterpret_cast、const_cast[转]

    C-style cast举例: int i; double d; i = (int) d; 上面的代码就是本来为double类型的d,通过(int)d将其转换成整形值,并将该值赋给整形变量i (注意d ...

  9. C++学习笔记(14) static_cast 与 dynamic_cast

    dynamic_cast运算符能够在运行时将一个对象强制转换成其实际类型: 实际应用场景:在C++学习笔记(13)中,在main.cpp里面定义了displayGeometric()函数, void ...

最新文章

  1. 3D视觉工坊中秋国庆贺礼!
  2. 什么是CUDA编程 统一计算架构
  3. django_mailgun.MailgunAPIError: Response [401]
  4. 长语音识别体验_如何为语音体验写作
  5. 基于python的图片修复程序-可用于水印去除
  6. 前端基础-html-段落标签
  7. Linux 用户态与内核态的交互——netlink 篇
  8. python scrapy框架爬虫_Python Scrapy爬虫框架
  9. php 压缩动态gif,php 压缩图片处理png、gif背景变黑问题
  10. c++笔记(10) 文件输入输出
  11. 读书笔记 effective c++ Item 34 区分接口继承和实现继承
  12. enctype=multipart/form-data 文件上传
  13. 梯度边缘检测 matlab,梯度边缘检测matlab
  14. Shell编程(CentOS7)
  15. java 图片处理 图片缩略图_java 生成图片缩略图
  16. OpenCV:鼠标画直线并显示坐标
  17. 字大小数据 - 快速取模的C++实现
  18. 融资买入:连续10天、7天
  19. svn 提交仍处于树冲突 One or more files are in a conflicted state
  20. 软件工程实践2018第四次作业——团队展示

热门文章

  1. oracle数据迁移过程中,把表中数据导出为txt文件的三种方法
  2. 原 oracle执行update一直处于执行中,跟卡住一样
  3. 怎样远程访问 MySQL
  4. 针对每个团队提出的意见和建议
  5. 4. Storm可靠性
  6. struts2的两个核心配置文件
  7. 数据库是.frm,.myd,myi备份如何导入mysql (转)
  8. unix 网络编程总结
  9. 如何为新建网站选择好的域名
  10. 再接再厉!Alphabet将携手更多汽车厂商测试无人驾驶