C++ RTTI中dynamic_cast的用法

gaopengtttt發表於2016-09-01
我們知道在C++中基類的指標和引用可以指向派生類,因為這是安全的,派生類一定包含了基類
需要的所有的屬性和方法,這是向上轉換,我們同時還知道虛擬函式可以隨著指標和引用指向的
物件不同而使用不同的方法,這是虛擬函式的自適應。
打個例子:

點選(此處)摺疊或開啟

  1. class testb
  2. {
  3.         private:
  4.                 int a;
  5.         public:
  6.                 testb(int ai){a=ai;}
  7.                 virtual void show(void) const
  8.                 {
  9.                         cout<<a<<endl;
  10.                 }
  11.                 virtual ~testb(){}
  12. };


  13. class testc:public testb
  14. {
  15.         private:
  16.                 int b;
  17.         public:
  18.                 testc(int ai,int bi):testb(ai),b(bi){}
  19.                 virtual void show(void) const
  20.                 {
  21.                         cout<<"test:"<<b<<endl;
  22.                 }
  23.                 void show2(void) const
  24.                 {
  25.                         cout<<"test2:"<<b<<endl;
  26.                         testb::show();
  27.                 }
  28.                 virtual ~testc(){}
  29. };


testb *p;
testc a(1,2);
testb b(1);
p可以指向派生類
p= &a;
p->show() 為派生類的testc::show();
p可以指向基類
p=&b;
p->show() 為基礎類的testb::show();

因為show()虛擬函式,這樣是可以完成。

但是我們考慮另外一種情況
testb *p;
testc a(1,2);
p= &a;
p->show2(); 是否能夠按照我們預想的呼叫到testc::show2()呢
答案是否定的,因為show2()根本就不是虛擬函式.只有虛擬函式才有這樣的自適應性,也就是根據指向物件的不同而呼叫合適的方法。
那麼我們是否可以
(testc* )p;
這樣處理呢,因為我們知道p指向是一定testc的派生類,我們將p指標轉換後為testc*是安全的,這樣處理是可以的。
這裡談到了安全,什麼時候是不安全的呢?考慮如下情況:
testb *p;
testb b(1);
p= &b;
(testc* )p;
這就是不安全的,因為做強制轉換將指向基礎類 testb的指標轉換為派生類testc指向那麼void show2(void) const是不存在的。
當然這裡我們可以人為判斷,但是不是任何時候都可以這樣,比如程式大了過後。我們需要一種方法來完成這樣的判斷工作,
那麼引入了RTTI dynamic_cast
dynamic_cast<Type *>(pt)
成功pt轉換為Type型別指標失敗返回0及空指標。
最後演示一下用法標頭檔案就是剛才給出的

點選(此處)摺疊或開啟

  1. #include<iostream>
  2. #include"dynamic_cast.h"
  3. using namespace std;


  4. int main(void)
  5. {
  6.         testb *p;
  7.         testb a(1);
  8.         testc b(1,100);
  9.         p=&a;

  10.         testc *q1 = dynamic_cast<testc*>(p);
  11.         if(!q1)
  12.         {
  13.                 cout<<"dynamic check cast of q1 failed!!"<<endl;
  14.         }
  15.         else
  16.         {
  17.                 q1->show2();
  18.         }

  19.         p=&b;

  20.         testc *q2 = dynamic_cast<testc*>(p);
  21.         if(!q2)
  22.         {
  23.                 cout<<"dynamic check cast of q2 failed!!"<<endl;
  24.         }
  25.         else
  26.         {
  27.                 q2->show2();
  28.         }


  29. }

輸出:
dynamic check cast of q1 failed!!
test2:100
1

沒有問題testc *q1 = dynamic_cast<testc*>(p);
返回了一個空指標
返回了dynamic check cast of q1 failed!!
第二個

testc *q2 = dynamic_cast<testc*>(p);
正常完成因為這個時候p指向是
testc b(1,100);

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2124368/,如需轉載,請註明出處,否則將追究法律責任。

相關文章