關於c++中運行時類型識別的問題


我寫這段的代碼的目的是,我想建立個鏈表。存儲所有的對象的指針,我想把他們都轉化成動物基類的指針,用的時候在轉換回來。
class animal
{
public:
animal(void);
~animal(void);
void virtual fly();
};
animal::animal(void)
{

}

animal::~animal(void)
{
}
void  animal::fly()
{
}

class bird :public animal
{
public:
bird();
~bird();
void fly();

};

class dog: public animal
{
public:
dog();
~dog();
void brak();
};


bird::bird()
{}
bird::~bird()
{}
void bird::fly()
{
std::cout<<"fly"<<std::endl;
}

dog::dog()
{}
dog::~dog()
{}
void dog::brak()
{}
// testRTTI.cpp : 定義控制台應用程序的入口點。
//

#include "stdafx.h"
#include ".\animal.h"
#include "test.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

bird birdObject;
dog dogObject;
animal* pointBird=&birdObject;
animal* pointDog=&dogObject;
if(typeid(*pointBird)==typeid(bird))
cout<<" find bird"<<endl;
else
cout<<"connot change "<<endl;
bird* pointB=dynamic_cast<bird*>(pointBird);
         //如果這的fly不是虛函數行嗎?
pointB->fly();
return 0;
}

這種運行時的轉換為什么不能執行阿,c++支持嗎?如果可以的話,怎么改這段代碼

19 个解决方案

#1


怎么不能執行?
以上代碼在gcc上無問題。

估計樓主用VC6而沒開RTTI吧。。。。

#2


在vc要先打開RTTI. 
還有這里fly是不是虛函數都行.但用dynamic_cast你這個animal類必須有個虛函數才行.

#3


我寫這段的代碼的目的是,我想建立個鏈表。存儲所有的對象的指針,我想把他們都轉化成動物基類的指針,用的時候在轉換回來。
======================
樓主看下boost的any和shared_ptr

#4


MFC的類型動態識別可以看看,不錯

#5


RTTI在VC中是默認關閉的(不只是VC6),可以在編譯設置中打開。

另外,RTTI一定要在類中有虛函數時才起作用,不過樓主的程序是沒用問題的。

不過在C++中不鼓勵使用動態類型判斷,慎之慎之。

#6


我寫這段的代碼的目的是,我想建立個鏈表。存儲所有的對象的指針,我想把他們都轉化成動物基類的指針,用的時候在轉換回來。
=================
使用 多態,
完美的解決 !!

#7


在基類中定義一些 基本的空 虛函數,
然后在 相應的 派生類中 重寫函數就可以了 ~~

對象傳遞使用基類類型的指針進行傳遞,
訪問方式使用指針訪問成員函數,
得到的就是實際類型的方法 ...

#8


http://www.cppblog.com/ivenher/articles/12264.html

#9


如果用多態的話,那是不是我的狗和鳥中的方法名字是一樣的啊!比如在基類定義10個虛函數,子類通過繼承只能重寫這些函數內容了。我用基類的指針只能得到這些虛的函數。還有我的子類函數不是虛的怎么辦。就像我的狗類里面自己在定義的方法,用基類的指針不是取不出來了。我就沒辦法實現我要的類型轉換。

#10


其實不用RTTI也可以,樓主只要定義一個虛函數,通過這個函數可以得到對象本身的指針.用的時候調用一下就可以了.如果想測試類型,可以加上類似COM的接口查詢機制.這種方法貌似比用RTTI快一點,也直接一點(其實RTTI也是類似的方式,只是再復雜點).

#11


RTTI在VC8中並不一定是默認關閉的~~ CLR工程就是默認打開的

#12


我覺得比較好的方法是自己給dog實現一個fly函數來報錯就可以了。
void dog::fly(){
   ERROR("I am a dog and I could not fly\n");
}

#13


請問redleaves(程序員) 
只要定義一個虛函數,通過這個函數可以得到對象本身的指針,這個怎么實現啊。比如
  dog dogObject;
  那么怎么在這個dog類里面實現獲得這個dogObject的指針的函數啊,
  dogObject.getPoint(dogObject)
   {
     dog* point=&dogObject;
   }
  這么寫行嗎?

#14


dogObject傳進去我用它的引用形式

#15


如果使用多態的話,那我在dog里面加的非虛函數。就沒辦法用鏈表里面存的基類指針調用了。

#16


呃,要上visitor模式或者double dispathc模式了。看設計模式,或者more effective c++ item 31

#17


只有你的類中至少有一個virtual成員函數時,RTTI才會真正起作用(即,在運行時刻給出類型的實際信息),如果類型沒有任何virtual函數,則RTTI是編譯時期的事情,此時會根據靜態聲明來給出相關信息,這是也就算不上真正的RTTI了。
還有,vc系列編譯器需要打開相應功能才可以有RTTI的。

#18


我來談談我的看法,這是本人理解,見笑了。如有錯誤,請立即指正。所謂RTTI,指的是runtime類型識別,主要有兩個特別的函數,iskindof,createobject.所以要實現RTTI還需要像mfc里面那樣構建類型識別網絡,由宏來做到。樓主的只是多態而以,要實現多態,就要用virtual,來構建虛擬指針表。
還有,dynamic_cast<>是不是提倡使用?應為這個轉型有花銷,他會一個一個比較你是不是父類的子類。如果就用普通轉型,應該會快,但是少了類型的判斷。lz自己看着辦拉。

#19


用virtual就搞定了啊

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: