首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 多重繼承指針問題:基類指針偏移、dynamic_cast、強轉陷阱

     編輯:關於C++

指針偏移現象


class Base1 { virtual void f1(); };
class Base2 { virtual void f2(); };
class Derive : public Base1, public Base2 { ... };

Derive d;
Base1* p1 = &d;      // 指向 Derive 起始地址 (Base1 子對象在最前)
Base2* p2 = &d;      // 指向 Base2 子對象地址 (偏移 sizeof(Base1))
// p1 == &d 為 true,p2 == &d 為 false
// 但 p1 == p2 在編譯器隱式轉換下為 true(比較邏輯地址)

內存佈局

Derive 對象:
[ Base1 部分 ] [ Base2 部分 ] [ Derive 自身部分 ]
   ↑ p1, &d         ↑ p2

強制轉換陷阱


Base1* p1 = &d;
Base2* p2 = (Base2*)p1; // 錯誤!強制轉換不調整偏移,p2 指向 Base1 內存
p2->f2(); // 未定義行為,可能調用 Base1::f1()(虛表錯位)

// 正確:dynamic_cast
Base2* p2 = dynamic_cast(p1); // 正確調整偏移

反向轉換風險


Base2* p2 = &d;
Base1* p1 = (Base1*)p2; // 可能崩潰!Base2 不在對象起始位置

核心規則

  1. 多重繼承下,基類指針轉換必須用 dynamic_cast(或 static_cast 但需確知佈局)
  2. C 風格強轉 (Type*) 不調整指針值,極度危險
  3. dynamic_cast 需虛函數支援,運行時檢查並調整偏移
  4. 避免多重繼承,或使用組合/介面隔離

驗證代碼


int main() {
    Derive d;
    cout << "&d=" << &d << "\n";
    Base1* p1 = &d;
    cout << "p1=" << p1 << "\n";
    Base2* p2 = dynamic_cast(p1);
    cout << "p2=" << p2 << "\n";
    p2->f2(); // 正確輸出 Derive::f2
    return 0;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved