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

從面向過程到面向對象:C++ 標準化考試系統重構實戰

     編輯:程式設計綜合問答

引言

許多初學者習慣用面向過程的風格編寫 C++ 代碼,但隨著項目規模增長,面向對象(OOP)的封裝、繼承、多態特性能顯著提升代碼的可維護性與擴展性。本文以一個「單項選擇題標準化考試系統」為例,演示如何將傳統的結構體鏈表實現重構為標準的 C++ 類設計。

原始架構分析

原代碼使用 struct question 形成單鏈表,所有操作(菜單、插入、查找、文件讀寫、答題邏輯)均為全局函數,數據與行為分離,存在全局變量污染、內存管理手動麻煩等問題。

重構核心步驟

1. 封裝數據結構

將 question 結構體作為內部節點,由 ExamSystem 類管理鏈表頭指針 head,對外隱藏實現細節:

class ExamSystem {
private:
    struct Node {
        char ask[200];
        char answer[4][80];
        int right;
        Node* next;
        Node() : next(nullptr) {}
    };
    Node* head;
    size_t count;  // 題目總數
public:
    ExamSystem() : head(nullptr), count(0) {}
    ~ExamSystem() { clear(); }
    // 公開介面...
};

2. 將全局函數轉為成員函數

  • menu():改為顯示菜單並返回選項的私有輔助函數。
  • insert():改為 addQuestion(const Node&),內部處理頭插法並更新 count。
  • seek():改為 getRandomStart(size_t n),利用 std::mt19937 替代 rand() 獲得更好隨機性。
  • loadfile/savefile:合併為 loadFromFile(FILE*) 和 saveToFile(FILE*),構造/析構時自動調用。
  • getquestion/getanswer/getyouranswer/explainquestion:分別對應 inputQuestion()、inputAnswer()、getUserAnswer()、evaluate(size_t n)。

3. 引入 RAII 與標準庫

使用 std::unique_ptr 或手動實現析構函數 clear() 釋放鏈表內存,避免洩漏;文件操作改用 std::fstream;輸入處理改用 std::getline 解決空格截斷問題。

關鍵改進點

原問題重構方案
手動 malloc/free 易出錯構造/析構函數自動管理生命周期
全局狀態 start, line封裝為類私有成員
scanf("%s") 無法讀取含空格標題std::getline(cin, str) 完整讀取行
隨機數 srand/rand 質量差<random> 引擎與分佈
答案統計邏輯與鏈表遍歷耦合分離為獨立評估方法,可單元測試

主程序簡化

int main() {
    ExamSystem exam;
    exam.loadFromFile("kstm.dat");
    cout << "***** 歡迎使用考試系統 *****\n";
    while (true) {
        switch (exam.showMenu()) {
            case 1: exam.inputQuestion(); break;
            case 2: exam.startQuiz(); break;
            case 3: exam.saveToFile("kstm.dat"); return 0;
        }
    }
}

總結

通過面向對象重構,系統獲得了清晰的模塊邊界、自動資源管理、更安全的輸入處理與現代 C++ 風格。這不僅是語法轉換,更是設計思維的升級——將「數據+操作」封裝為有職責的對象,為後續擴展(如多題型、統計分析、GUI)奠定基礎。

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