首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ dynamic_cast 多態識別:正確判斷對象動態類型的寫法

     編輯:程式設計綜合問答

題目要求

實現 string verify(A* a),根據傳入指針指向的實際類型返回:

  • A → "grandpa"
  • B : public A → "father"
  • C : public B → "son"

錯誤代碼分析

string verify(A* a) {
    A* a1 = dynamic_cast<A*>(a);  // 無意義,永遠成功
    B* b1 = dynamic_cast<B*>(a);  // 缺少模板參數
    C* c1 = dynamic_cast<C*>(a);  // 缺少模板參數
    if (a1) return "grandpa";      // 順序錯誤,父類先匹配導致子類永不命中
    if (b1) return "father";
    if (c1) return "son";
}

正確寫法

string verify(A* a) {
    // 從最派生類向基類檢查
    if (dynamic_cast<C*>(a)) return "son";
    if (dynamic_cast<B*>(a)) return "father";
    return "grandpa";  // 只有 A 對象走到這裡
}

關鍵點總結

  1. 檢查順序:必須 子類優先,否則基類指針永遠能轉換成功,屏蔽派生類判斷。
  2. 語法完整:dynamic_cast<TargetType*>(sourcePtr),模板參數不可省略。
  3. RTTI 前提:編譯器需開啟 RTTI (/GR VC++, -frtti GCC),且類必須有虛函數(題目中 A 有虛析構)。
  4. 空指針安全:傳入 nullptr 時 dynamic_cast 返回 nullptr,上述邏輯會返回 "grandpa",如需區分可先判空。

性能替代方案

若極度敏感,可用 虛函數分發 避免 RTTI 開銷:

class A { public: virtual string verify() { return "grandpa"; } virtual ~A(){} };
class B : public A { public: string verify() override { return "father"; } };
class C : public B { public: string verify() override { return "son"; } };

string verify(A* a) { return a->verify(); }  // 雙分發,O(1) 虛表查找
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved