#include <iostream>
using namespace std;
class A {
public:
int _a;
A() { _a = 1; printf("A construct\n"); }
void print() { printf("%d,", _a); }
};
class B : public A {
public:
int _a; // 同名成員遮蔽基類
B() { _a = 2; printf("B construct\n"); }
};
int main() {
B b;
b.print(); // 調用基類 A::print()
printf("%d", b._a); // 訪問派生類 B::_a
return 0;
}
A construct
B construct
1,2
B::_a 遮蔽 A::_a,兩者獨立佔用內存[A::_a][B::_a](單繼承無虛函數時)b.print() 調用 A::print(),內部訪問 this->_a 解析為 A::_a → 輸出 1b._a 直接訪問派生類作用域成員 → 輸出 2
B 對象內存:
+--------+--------+
| A::_a | B::_a | ← 兩個獨立 int
+--------+--------+
offset0 offset4 (32位系統)
A::print() 編譯為:
mov eax, [this] ; this 指向 B 對象起始
mov eax, [eax] ; 取 offset 0 → A::_a
push eax
call printf
b._a 編譯為:
mov eax, [this+4] ; 取 offset 4 → B::_a
push eax
call printf
b.A::_a = 10; // 顯式作用域限定
b.A::print(); // 顯式調用基類版本
static_cast(b)._a = 20; // 強轉基類引用
m_a vs a_)virtual,否則刪除基類指針導致派生類析構不被調用本文整理自「天才鳥蛋」博客,原文地址:https://curely.blog.51cto.com/1627940/1297701