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

C++ 類與繼承實戰演練:賬戶體系、多重繼承構造順序、菱形問題

     編輯:關於C++

案例一:單繼承 — 賬戶與信用賬戶

需求:基類 Account 存用戶名,派生類 CreditAccount 增加信用額度,PrintInfo() 調用基類 PrintName()。


#include 
#include 
using namespace std;

class Account {
    string userName;
public:
    Account() = default;
    Account(const string& name) : userName(name) {}
    void PrintName() const { cout << userName << endl; }
};

class CreditAccount : public Account {
    int credit;
public:
    CreditAccount(const string& name, int credit) : Account(name), credit(credit) {}
    void PrintInfo() const {
        PrintName();          // 調用基類公有函數
        cout << credit << endl;
    }
};

int main() {
    CreditAccount acc("I Love CPP", 10000);
    acc.PrintInfo(); // 輸出兩行:用戶名 + 額度
}

關鍵點:派生構造函數**初始化列表**顯式調用基類構造 Account(name),否則編譯器嘗試調用基類無參構造 (若無則報錯)。

案例二:多重繼承 — 構造/析構順序鐵律

代碼:


class Base1 { public: Base1(int x) { cout << "Base1 ctor " << x << endl; } ~Base1() { cout << "Base1 dtor" << endl; } };
class Base2 { public: Base2(int x) { cout << "Base2 ctor " << x << endl; } ~Base2() { cout << "Base2 dtor" << endl; } };
class Base3 { public: Base3(int x) { cout << "Base3 ctor " << x << endl; } ~Base3() { cout << "Base3 dtor" << endl; } };

class Derived : public Base2, public Base1, public Base3 { // 繼承聲明順序!
public:
    Derived(int x1, int x2, int x3, int x4) : Base1(x2), Base2(x3), Base3(x4) {
        cout << "Derived ctor " << x1 << endl;
    }
    ~Derived() { cout << "Derived dtor" << endl; }
};

輸入 1 2 3 4 輸出:

Base2 ctor 3
Base1 ctor 2
Base3 ctor 4
Derived ctor 1
Derived dtor
Base3 dtor
Base1 dtor
Base2 dtor

鐵律總結

  1. 構造順序:**虛基類 → 非虛基類 (按繼承聲明順序) → 成員對象 (聲明順序) → 派生類自身**。
  2. 析構順序:嚴格**逆序** (派生 → 成員 → 基類 → 虛基類)。
  3. 初始化列表寫法順序不影響實際調用順序,但為可讀性建議與聲明順序一致。

案例三:多重繼承數據成員同名 — 作用域解析

場景:Base1、Base2 各有 int x,Derived 繼承兩者並有自己的 x,需訪問各自 x。


struct Base1 { int x; Base1(int x):x(x){} };
struct Base2 { int x; Base2(int x):x(x){} };
struct Derived : public Base1, public Base2 {
    int x;
    Derived(Base1& a, Base2& b) : Base1(a.x), Base2(b.x), x(a.x + b.x) {}
};
int main() {
    Base1 a(1); Base2 b(2);
    Derived d(a, b);
    cout << d.Base1::x << "+" << d.Base2::x << "=" << d.x << endl; // 1+2=3
}

必須用 Base1::x、Base2::x 顯式指定作用域,否則編譯錯誤「ambiguous」。

進階:菱形繼承與虛基類


class Base { public: int v; Base(int v):v(v){} };
class Left : virtual public Base { public: Left(int v):Base(v){} };
class Right : virtual public Base { public: Right(int v):Base(v){} };
class Bottom : public Left, public Right {
public:
    Bottom(int v) : Base(v), Left(v), Right(v) {} // 必須由最底層派生類直接初始化虛基類
};
  • virtual 繼承確保 Bottom 僅包含**一份** Base 子對象 (解決數據冗餘與二義性)。
  • 虛基類由**最派生類**構造函數直接初始化,中間類調用被忽略。

總結

C++ 繼承機制嚴格規範了構造/析構順序與名稱查找規則。掌握 初始化列表調用基類構造、多重繼承聲明順序決定構造順序、同名成員用作用域解析、菱形問題用虛基類,即可駕馭複雜類層次設計。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved