关于C++中的dynamic cast的使用

浏览:27日期:2023-04-22

问题描述

C++ primer中看到这个dynamic cast, 有点搞不太懂. 这个dynamic cast的作用到底是干嘛? 如果说一个父类指针中实际指向一个子类的话, 如果用这个指针调用一个虚函数, 就算没有dynamic-cast也会发生动态绑定吧? 如果用这个指针调用一个子类独有的函数, 那么这里应该用static cast, 好像和dynamic cast 也没什么关系? 那就不懂了, dynamic cast到底有什么用...

按照1L的回复我写了如下代码 :

//p.hclass P{};//s.h#include 'p.h'class S : public P{};//main.cpp#include <iostream>#include 's.h'int main(){ //std::shared_ptr<P> x(new S); //std::shared_ptr<S> y = std::dynamic_pointer_cast<S>(x); P* x = new S; S* y = dynamic_cast<S*>(x);}

结果报错 :

main.cpp:8:12: error: ’P’ is not polymorphic S* y = dynamic_cast<S*>(x); ^~1 error generated.

问题解答

回答1:

dynamic_cast is typically used for down-cast check. e.g.

class Base{// .... // Base must be polymorphic!!! (has virtual members)virtual void foo();};class Derive: public Base{virtual void foo() override {cout<<'Derive::foo()'<<endl;}void derive_only() {cout<<'this method only exists for derive typen';}};Base* pDerive = new Derive();Derive* pd;if((pd = dynamic_cast<Derive*>(pDerive)){//downcast successful pd->derive_only(); // prints 'derive only method'}else{//the pDerive is not Derive type}回答2:

谢邀。前面已经有人回答得很好了,这里就不再对dynamic_cast的用法多做赘述了。

这里主要说一下为什么要用到dynamic_cast,前面也右回答,是更安全。还有,需要在指向同一个对象的不同基类指针之间的转换,使用dynamic_cast能够保证转换的正确性。还有就是基类类型的指针,指向可以不同子类对象。但是两个子类类型的指针,是不能指向对方的对象的。如果转换,是会出错的。这时候可以使用dynamic_cast在运行时判断基类指针指向的是哪一个子类的对象。

举一个例子。http://ideone.com/oUgVpo

#include <iostream>using namespace std;class A { public: virtual ~A(){} int a;};class B{ public: virtual ~B(){} int b;};class AB : virtual public B,virtual public A {};int main(){ AB *pab = new AB(); A* pa = (A*)pab; // AB先继承的B,所以pa指向的是后16个字节 B* pb = (B*)pab; // pb指向前16个字节 cout<<'pab = '<<pab<<'npa = '<<pa<<'npb = '<<pb<<endl; // 注意差值,包含了虚基类指针 cout<<dynamic_cast<AB*>(pa)<<endl; // 源类型是多态,可以转换 // cout<<static_cast<AB*>(pa)<<endl; // 不能转换,多态类型需要使用dynamic_cast来转换 return 0;}回答3:

dynamic_cast具有类型检查的功能,失败会抛出bad_cast异常。比static_cast更安全,static_cast是不作任何检查直接强转的

回答4:

经过我反复试验, 发现只要在父类中加入一个虚函数, 或者把析构函数设为虚函数就可以了, 但是并不知道为什么会这样...

回答5:

最简单的例子:

class Father{public: virtual void func1() { std::cout << 'Father' << std::endl; } virtual ~Father(){}};class Son :public Father{public: virtual void func1(){ std::cout << 'Son1' << std::endl; } void func2(){ std::cout << 'Son2' << std::endl; } virtual ~Son(){}};class Factory{private: Father* myFather;public: void setFun(Father* m_Father) { myFather = m_Father; } Father* getFun() { return myFather;};};int main(){ Father *m_Father = new Father(); Factory* m_Factory = new Factory(); m_Factory->setFun(m_Father ); m_Factory->getFun()->func1(); dynamic_cast<Son*>(m_Factory->getFun())->func2(); /// return 0;}回答6:

http://stackoverflow.com/ques...

回答7:

dynamic_cast 转换的依据是虚表前面的 type_info 进行转换,只有包含虚函数的类才可以使用 dynamic_cast 。

而且上述的 type_info 是在编译期由编译器生成,所以在编译的时候,如果没有找到 type_info,就会报错。

相关文章: