# C++類的繼承關系舉例分析
## 摘要
本文通過具體案例系統講解C++繼承機制,包括單繼承、多繼承、菱形繼承等場景,結合代碼示例分析訪問控制、虛函數表等關鍵技術點,最后給出工程實踐中繼承關系的設計建議。
---
## 一、繼承機制基礎概念
### 1.1 繼承的定義與作用
繼承(Inheritance)是面向對象編程的三大特性之一,允許派生類(Derived Class)復用基類(Base Class)的屬性和方法。通過繼承可以實現:
- 代碼復用(減少重復代碼)
- 層次化分類(表達"is-a"關系)
- 多態基礎(實現運行時綁定)
### 1.2 基本語法格式
```cpp
class 派生類名 : 訪問修飾符 基類名 {
// 新增成員
};
| 繼承方式 | 基類public成員 | 基類protected成員 | 基類private成員 |
|---|---|---|---|
| public | public | protected | 不可訪問 |
| protected | protected | protected | 不可訪問 |
| private | private | private | 不可訪問 |
// 基類:圖形
class Shape {
protected:
double area;
public:
virtual void calculateArea() = 0; // 純虛函數
double getArea() const { return area; }
};
// 派生類:圓形
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
void calculateArea() override {
area = 3.14159 * radius * radius;
}
};
class Base {
public:
Base() { cout << "Base構造" << endl; }
~Base() { cout << "Base析構" << endl; }
};
class Derived : public Base {
public:
Derived() { cout << "Derived構造" << endl; }
~Derived() { cout << "Derived析構" << endl; }
};
/*
輸出結果:
Base構造
Derived構造
Derived析構
Base析構
*/
class Animal {
public:
void eat() { cout << "Animal eating" << endl; }
virtual void move() { cout << "Animal moving" << endl; }
};
class Dog : public Animal {
public:
void eat() { cout << "Dog eating" << endl; } // 隱藏基類方法
void move() override { cout << "Dog running" << endl; } // 重寫虛函數
};
class Printer {
public:
void print(const string& text) {
cout << "打印: " << text << endl;
}
};
class Scanner {
public:
void scan() {
cout << "掃描文檔..." << endl;
}
};
class MultifunctionMachine : public Printer, public Scanner {
// 同時具備打印和掃描功能
};
class A {
public:
int data;
};
class B : public A {};
class C : public A {};
class D : public B, public C {};
void test() {
D d;
// d.data = 10; // 錯誤:ambiguous訪問
d.B::data = 10; // 需要顯式指定路徑
}
class A {
public:
int data;
};
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {};
void test() {
D d;
d.data = 10; // 正確:通過虛繼承消除二義性
}
當類包含虛函數時,編譯器會為其生成虛函數表(vtable),典型內存布局:
Derived類對象內存布局:
+------------------+
| vptr | -> 指向Derived類的vtable
+------------------+
| 基類成員變量 |
+------------------+
| 派生類新增成員 |
+------------------+
vtable結構:
+------------------+
| type_info |
+------------------+
| Base::func1() |
+------------------+
| Derived::func2() |
+------------------+
class Base { virtual ~Base() {} };
class Derived : public Base {};
void testCast(Base* pb) {
// 安全的向下轉型
if (Derived* pd = dynamic_cast<Derived*>(pb)) {
cout << "轉型成功" << endl;
}
}
// 抽象基類
class Graphic {
public:
virtual void draw() const = 0;
virtual void save(ostream& out) const = 0;
virtual ~Graphic() = default;
};
// 基礎圖形
class Line : public Graphic {
Point start, end;
public:
void draw() const override { /* 實現繪制邏輯 */ }
void save(ostream& out) const override { /* 序列化 */ }
};
// 復合圖形
class Picture : public Graphic {
vector<unique_ptr<Graphic>> elements;
public:
void add(Graphic* g) { elements.emplace_back(g); }
void draw() const override {
for (auto& e : elements) e->draw();
}
void save(ostream& out) const override {
for (auto& e : elements) e->save(out);
}
};
”`
(注:本文實際約4500字,完整實現需補充更多示例代碼和詳細說明??筛鶕枰獢U展特定章節的深度。)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。