static_cast与dynamic_cast转换
来源:互联网 发布:支付宝如何解绑淘宝号 编辑:程序博客网 时间:2024/05/18 00:58
static_cast与dynamic_cast转换
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)
1 static_cast
(1)用于基本的数据类型转换(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); //errorvoid *p = static_cast<void*>(pa);pb = static_cast<int*>(p);pc = static_cast<char*>(p);
(2)类层次中基类与子类成员函数指针的转换
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); //基类指向子类成员函数指针,必须进行转换
(3)类层次结构中基类与子类指针或引用之间的转换
上行转换:子类指针或引用转换成基类表示——安全
下行转换:基类指针或引用转换成子类表示——危险(没有动态类型检查)
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 两个无关联之间转换
2 dynamic_cast
(1)继承关系的类指针对象或引用之间转换
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 没有关系 不是多态类型不能转换
(2)包含有虚函数之间对象指针的转换
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转换必须具有虚函数才行。
那这是为什么呢?下面继续>
(3)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转换
- static_cast与dynamic_cast转换
- static_cast与dynamic_cast转换
- static_cast与dynamic_cast转换
- static_cast与dynamic_cast转换
- static_cast与dynamic_cast转换
- static_cast与dynamic_cast转换
- static_cast与dynamic_cast转换
- static_cast与dynamic_cast转换
- static_cast与dynamic_cast转换
- static_cast与dynamic_cast转换
- static_cast与dynamic_cast转换
- dynamic_cast与static_cast讨论
- static_cast 与dynamic_cast
- dynamic_cast与static_cast
- dynamic_cast,static_cast与typeid
- 浅议 Static_cast 与 Dynamic_cast
- static_cast与dynamic_cast
- linux安装keystone的问题
- 如此好用的手持车牌识别软件,你拥有了嘛!
- 通信行业课程名称
- 编写一个Activity基类,对Activity进行封装,方便使用
- 【SpringMVC】关于classpath和contextConfigLocation
- static_cast与dynamic_cast转换
- Android中的xmlns:解析
- spice-client源码解析之process_loop.cpp
- Mysql中不支持的Oracle函数
- 一般人不告诉的精通linux系统秘籍
- 【第十一周项目1】图基本算法库
- 【笨鸟先飞】Java重新学习日记13--创建一个内部类
- 第九周项目1
- 第十一周——项目三—图的遍历