关于C++中的dynamic cast的使用
阿神
阿神 2017-04-17 14:24:28
0
7
626

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

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

//p.h
class 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.
阿神
阿神

闭关修行中......

全部回覆(7)
刘奇

dynamic_cast 通常用於向下轉換檢查。例如

雷雷
Peter_Zhu

謝邀。
前面已經有人回答得很好了,這裡就不再對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;
}
伊谢尔伦

dynamic_cast具有類型檢查的功能,失敗會拋出bad_cast異常。比static_cast安全,static_cast是不作任何檢查直接強轉的

大家讲道理

經過我反覆試驗, 發現只要在父類中加入一個虛函數, 或者把析構函數設為虛函數就可以了, 但是並不知道為什麼會這樣...

Ty80

最簡單的例子:

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;
}
左手右手慢动作

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

伊谢尔伦

dynamic_cast 轉換的依據是虛表前面的 type_info 進行轉換,只有包含虛函數的類別才可以使用 dynamic_cast 。

而且上述的 type_info 是在編譯期由編譯器生成,所以在編譯的時候,如果沒有找到 type_info,就會報錯。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板