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

C++ OOP 練習:足球隊員類別設計與成員查詢完整實作

     編輯:程式設計綜合問答

題目需求分析

  1. 定義 Member 類別,包含姓名 (string) 與年齡 (int),兩者皆為常數 (const)。
  2. 支援 cout << member 輸出格式:姓名 年齡;若年齡為 0 則顯示 ???。
  3. 主程式建立 5 元素陣列,前 4 個有姓名年齡,第 5 個預設建構 (姓名空、年齡 0)。
  4. 定義 MemberList 類別,建構子接受 Member* 與長度,支援 list[name] 透過姓名查詢年齡。

完整程式碼實作

#include 
#include 
#include 
#include 
using namespace std;

// ==================== Member 類別 ====================
class Member {
    const string name;   // 常數成員
    const int age;       // 常數成員
public:
    // 預設建構子:產生 "???" 隊員
    Member() : name(""), age(0) {}
    
    // 參數建構子
    Member(const string& n, int a) : name(n), age(a) {}
    
    // 輸出運算子多載 (友元函數)
    friend ostream& operator<<(ostream& os, const Member& m) {
        if (m.age == 0) {
            os << "???";
        } else {
            os << m.name << " " << m.age;
        }
        return os;
    }
    
    // 提供查詢介面給 MemberList 使用
    const string& GetName() const { return name; }
    int GetAge() const { return age; }
};

// ==================== MemberList 類別 ====================
class MemberList {
    vector members;  // 使用 vector 管理動態陣列
public:
    // 建構子:從 Member 陣列複製
    MemberList(const Member* arr, int count) {
        for (int i = 0; i < count; ++i) {
            members.push_back(arr[i]);
        }
    }
    
    // 索引器:透過姓名查詢年齡
    int operator[](const string& name) const {
        for (const auto& m : members) {
            if (m.GetName() == name) {
                return m.GetAge();
            }
        }
        throw out_of_range("Member not found: " + name);
    }
};

// ==================== 主程式 ====================
int main() {
    // 建立 5 個隊員 (第 5 個使用預設建構子)
    Member newCommers[5] = {
        Member("Zhang San", 22),
        Member("Li Si", 19),
        Member("Wang Wu", 18),
        Member("Zhao Liu", 24)
        // 第 5 個自動為 Member() -> "???"
    };
    
    // 輸出所有隊員
    cout << "=== 隊員名單 ===" << endl;
    for (int i = 0; i < 5; ++i) {
        cout << newCommers[i] << endl;
    }
    
    // 建立查詢清單
    MemberList list(newCommers, 5);
    string names[5] = {"Zhang San", "Li Si", "Wang Wu", "Zhao Liu", "Pin Yin"};
    
    cout << "\n=== 年齡查詢 ===" << endl;
    for (int i = 0; i < 5; ++i) {
        try {
            int age = list[names[i]];
            cout << names[i] << " : " << age << endl;
        } catch (const out_of_range& e) {
            cout << names[i] << " : Not Found" << endl;
        }
    }
    
    return 0;
}

執行結果

=== 隊員名單 ===
Zhang San 22
Li Si 19
Wang Wu 18
Zhao Liu 24
???

=== 年齡查詢 ===
Zhang San : 22
Li Si : 19
Wang Wu : 18
Zhao Liu : 24
Pin Yin : Not Found

關鍵設計點解析

1. const 成員變數與初始化列表

const 成員必須在建構子初始化列表中初始化,無法在建構子本體內指派:

Member(const string& n, int a) : name(n), age(a) {}  // ✅ 正確
// Member(const string& n, int a) { name = n; age = a; }  // ❌ 編譯錯誤

2. 友元函數多載 << 運算子

  • 宣告為 friend 以存取 private const 成員。
  • 參數為 const Member& 避免複製,回傳 ostream& 支援串接。
  • 輸出格式符合題目:年齡 0 顯示 ???,否則 姓名 年齡。

3. MemberList 使用 vector 而非原始陣列

  • 自動管理記憶體,避免手動 new/delete。
  • 建構子接受 const Member* 與計數,相容題目要求的介面。
  • operator[] 回傳 int (年齡),找不到拋出例外 (或可改回傳 -1/optional)。

4. 例外處理與健壯性

查詢不存在姓名時拋出 std::out_of_range,主程式捕獲並顯示 Not Found,符合題目「查詢 5 個名稱」的需求 (第 5 個 Pin Yin 不存在)。

進階擴充建議

  • 使用 std::unordered_map 將查詢複雜度從 O(n) 降為 O(1)。
  • 加入 std::optional (C++17) 避免例外開銷:optional operator[](const string&) const。
  • 實作複製/移動語意 (Rule of Five),雖然 vector 已自動處理。
  • 單元測試:驗證預設建構子、輸出格式、查詢正確性、邊界條件。

常見錯誤避雷

錯誤原因修正
const 成員未在初始化列表初始化C++ 規定 const 成員只能在初始化列表設值使用 Member() : name(""), age(0) {}
operator<< 非友元無法存取 privateprivate 成員外部不可存取加 friend 宣告或提供 public getter
MemberList 建構子未複製資料直接存指標導致懸空指標用 vector 深度複製或 shared_ptr
查詢不存在姓名未處理題目要求查詢 5 個名稱含 1 個不存在拋出例外或回傳特殊值
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved