C++类的使用(六)—— 判断继承
相信通過之前的學習,你也已經對類有了深刻的了解,那么請利用你所學的知識,想一想下面這道題。
/* 函數名: foo* 函數聲明:* template <class B, class D>* bool foo();* 函數注解:* B代表判斷基類* D代表判斷子類* foo返回一個布爾值* 如果D是B的子類,返回true* 如果D不是B的子類,返回false*/很新奇的題目吧,你可能一下子被蒙住了。這道題牽涉到函數重載(overload),下面就是本題答案。
/* 函數名: foo* 函數聲明:* template <class B, class D>* bool foo();* 函數注解:* B代表判斷基類* D代表判斷子類* foo返回一個布爾值* 如果D是B的子類,返回true* 如果D不是B的子類,返回false*/template <class B, class D> class Inherit { public:bool result(); protected:bool foo(B *var);bool foo(void *var); }; bool Inherit::result() {D *d = 0;return foo(0); } bool Inherit::foo(B *var) {return true;} bool Inherit::foo(void *var) {return false;}template <class B, class D> bool foo() {return Inherit<B,D>().result();}思路就是,通過函數重載,對于B的子類,將調用bool foo(B *var),對于其他類型,將調用bool foo(void *var)
這是因為從子類指針到父類指針比從指針到void *的距離短
當然我一開始也并不覺得是這樣,因為這怎么又可比性呢?我認為會報錯的。
但我親自嘗試了一下,發現確實可行。
再來一道和多態有關的。
這道題有點繞,舉個例子
class A {}; class B: public A {}; class C {};int main() {A *a = new B;foo<B>(a); // 返回true,因為a的類型是B,B是B的子類foo<C>(a); // 返回false,因為a的類型是B,B不是C的子類B *b = new B;foo<A>(b); // 返回true,因為b的類型是B,B是A的子類delete a.b; }就需要滿足上述的效果。
這道題要用到動態類型轉換(dynamic cast),你可能不知道
代碼很短,主要是第3行的dynamic_cast,這個運算符可以幫助我們判斷var是不是D的子類
dynamic_cast允許把一個原本為子類的父類變量轉為原本類型的父類。
聽起來有點繞口,其實很簡單。
假如A->B->C,即C是B的子類,B是A的子類
現有變量C *var,利用多態特性轉換為A *var,那么我們就不能直接看出var是否繼承B,這時dynamic_cast可以試圖將var轉換為B *類型,如果成功,返回轉換后的值,如果失敗,返回空指針。
這就正好滿足了我們的需求。
但dynamic_cast運行較慢,好像是通過源代碼查找的方式確定的。
所以能用第一種就用第一種。
本序列的文章:
C++類的使用(一)
C++類的使用(二)—— explicit構造與const成員變量賦值
C++類的使用(三)—— 封裝
C++類的使用(四)—— 繼承
C++類的使用(五)—— 多態
C++類的使用(六)—— 判斷繼承
總結
以上是生活随笔為你收集整理的C++类的使用(六)—— 判断继承的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++类的使用(五)—— 多态
- 下一篇: springmvc整合swagger 与