您的位置 首页 > 问答

C++用dynamic_cast将父类指针转换为子类指针,为什么不一定成功

[本站 C++用dynamic_cast将父类指针转换为子类指针,为什么不一定成功dynamic_cast的使用的问题dynamic_cast的用法c++中,dynamic_cast是什么作用C++用dynamic_cast将父类指针转换为子类指针,为什么不一定成功dynamic_cast的运用实…

C++用dynamic_cast将父类指针转换为子类指针,为什么不一定成功

  • dynamic_cast 的使用的问题
  • dynamic_cast的用法
  • c++中,dynamic_cast是什么作用
  • C++用dynamic_cast将父类指针转换为子类指针,为什么不一定成功
  • dynamic_cast的运用实例
  • c++关于 dynamic_cast的问题


在实用显示的强制类型
dynamic_cast
的时候,在VC6.0下需要设置,才可以使用。
工程(projece)-》设置(setting)
在里面知道C/C++那个选项。
然后在下面分类中选
C++语言
然后在
勾中下面一个选项
叫允许时间类型信息(RTTI)
然后确定就可以使用了。
否则的话,是不可以使用的,运行会出错。

dynamic_cast 《type-id》 (expression)
该运算符把expression转换成type-id类型的对象。Type-id 必须是类的指针、类的引用或者void*;
如果 type-id 是类指针类型,那么expression也必须是一个指针,如果 type-id 是一个引用,那么 expression 也必须是一个引用。
dynamic_cast运算符可以在执行期决定真正的类型。如果 downcast 是安全的(也就说,如果基类指针或者引用确实指向一个派生类对象)这个运算符会传回适当转型过的指针。如果 downcast 不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。 classB{public:int?m_iNum;virtual?void?foo();};classD:publicB{public:char*?m_szName;};void?func(B*?pb){D*?pd1=static_cast《D*》(pb);D*?pd2=dynamic_cast《D*》(pb);}在上面的代码段中,如果 pb 指向一个 D 类型的对象,pd1 和 pd2 是一样的,并且对这两个指针执行 D 类型的任何操作都是安全的;但是,如果 pb 指向的是一个 B 类型的对象,那么 pd1 将是一个指向该对象的指针,对它进行 D 类型的操作将是不安全的(如访问 m_szName),而 pd2 将是一个空指针。
另外要注意:B 要有虚函数,否则会编译出错;static_cast则没有这个限制。
这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念,详细可见《Inside c++ object model》)中,只有定义了虚函数的类才有虚函数表,没有定义虚函数的类是没有虚函数表的。


dynamic_cast
用于多态性的父子类型对象的指针或引用之间。
class A {
public:
virtual ~A (void) {}
};
class B : public A {};
class C : public B {};
int main (void) {
B b;
A* pa = &b
cout 《《 “pa = “ 《《 pa 《《 endl;
cout 《《 “---- dynamic_cast ----“ 《《 endl;
// pa实际指向B对象,转换成功
B* pb = dynamic_cast《B*》 (pa);
cout 《《 “pb = “ 《《 pb 《《 endl;
// pa没有指向C对象,转换失败
C* pc = dynamic_cast《C*》 (pa);
cout 《《 “pc = “ 《《 pc 《《 endl;//这里应该pc=NULL
}


这个问题牵扯到c++的对象模型。一般认为子类对象大小》=父类对象大小。为什么?因为子类可以扩展父类,可以增加成员变量。如果一个子类增加了成员变量,那么它的对象的内存空间会大于父类对象。这时一个实际指向父类的指针,如果被强制转化为子类对象指针,当使用这个指针时可能会导致越界访问非法内存。相反,为何子类指针可以转换为父类指针?因为父类指针需要的,子类对象都有,不会出现非法内存访问。
这就是dynamic_cast不一定成功的原因。如果一个实际指向子类对象的指针被转换成了父类指针,然后再用dynamic_cast转换回来,一定能成功,而一个实际指向父类对象的指针,被dynamic_cast转换为子类指针,一定会失败。

1)什么时候应必须使用dynamic_cast
2)什么时候dynamic_cast可以使用static_cast代替 //TestCast.cpp:Definestheentrypointfortheconsoleapplicationhttps://www.bjygyt.com/hynews//#include“stdafx.h“#include《iostream》usingnamespacestd;classBase{public:virtualvoidf(){cout《《“Base::f“《《endl;}voidf1(){cout《《“Base::f1“《《endl;}private:doublex;doubley;};classDerived:publicBase{public:virtualvoidf(){cout《《“Derived::f“《《endl;}virtualvoidk(){cout《《“Derived::k“《《endl;}private:doublez;};classBase1{public:virtualvoidg(){cout《《“Base1::g“《《endl;}voidg1(){cout《《“Base1::g1“《《endl;}};classDerived1:publicBase,publicBase1{public:virtualvoidf(){cout《《“Derived1::f“《《endl;}virtualvoidh(){cout《《“Derived1::h“《《endl;}};voidTest1(){//对于单继承,//如果pD真的指向Derived,用dynamic_cast和static_cast效果相同Base*pD=newDerived;Derived*pD1=dynamic_cast《Derived*》(pD);pD1-》f();pD1-》k();pD1-》f1();Derived*pD2=static_cast《Derived*》(pD);pD2-》f();pD2-》k();pD2-》f1();//但是如果pB不是真的指向Derived,则用dynamic_cast则返回NULL,能够更早的禁止error的发生,//如果用static_cast虽然返回的不为NULL,但是运行时可能抛出exception。/**/////Errorcode//Base*pB=newBase();//Derived*pD3=static_cast《Derived*》(pB);//pD3-》f();//pD3-》k();//pD3-》f1();//Derived*pD4=dynamic_cast《Derived*》(pB);//pD4-》f();//pD4-》k();//pD4-》f1();}voidTest2(){//对于多重继承,//如果pD真的指向的是Derived1,使用dynamic_cast和static_cast都可以转化为Derived1,//但是如果要转化为Base的兄弟类Base1,必须使用dynamic_cast,使用static_cast不能编译。Base*pD=newDerived1;Derived1*pD1=dynamic_cast《Derived1*》(pD);pD1-》f();pD1-》h();pD1-》f1();Base1*pB1=dynamic_cast《Base1*》(pD);pB1-》g();Derived1*pD2=static_cast《Derived1*》(pD);pD2-》f();pD1-》h();pD2-》f1();/**/////errorcannotcompiler//Base1*pB2=static_cast《Base1*》(pD);//pB2-》g();//当然对于pB不是真的指向Derived1,想要转化为Derived1或Base的兄弟类Base1,情况与Test1中的error情况相同。}int_tmain(intargc,_TCHAR*argv){Test1();Test2();return0;}


在实用显示的强制类型
dynamic_cast
的时候,在vc6.0下需要设置,才可以使用。
工程(projece)-》设置(setting)
在里面知道c/c++那个选项。
然后在下面分类中选
c++语言
然后在
勾中下面一个选项
叫允许时间类型信息(rtti)
然后确定就可以使用了。
否则的话,是不可以使用的,运行会出错。


相关tag:dynamiccast
本站部分资源来源于网络,如果侵犯了您的权益,请联系我们删除1354090129@qq.com

标签:指针   id   对象

本文来自网络,不代表94汽车车网立场,所有(图文、音视频)均由用户自行上传分享,仅供网友学习交流,版权归原作者。若您的权利被侵害,请联系 56325386@qq.com 删除。转载请注明出处:https://94che.com/qc/169131.html

发表回复

您的电子邮箱地址不会被公开。

返回顶部