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

C++ 圖書管理系統核心類 Libary 深度解析:構造函數、登錄流程與依賴關係

     編輯:程式設計綜合問答

代碼結構概覽

`Libary` 類作為系統**核心控制器**,協調數據庫訪問、用戶角色管理、業務流程調度。

關鍵成員變量解析


class Libary {
private:
    Chaxun se;              // 數據庫查詢封裝類(MySQL 連接、SQL 執行)
    Manager *manager;       // 普通管理員對象指針
    Reader *read;           // 讀者對象指針
    SuManager *sumanag;     // 超級管理員對象指針
public:
    Ways *way;              // 界面交互類(菜單顯示、輸入獲取)

    // 構造函數:依賴注入數據庫配置
    Libary(string ip="127.0.0.1", string id="root", string pwd="root", 
           string db="test", int port=3306)
        : se(ip.c_str(), id.c_str(), pwd.c_str(), db.c_str(), port),
          manager(NULL), read(NULL), sumanag(NULL) {}
    // ...
};
  • se (Chaxun):封裝 MySQL C API,提供 `Demand_str_one` 等查詢接口,構造時建立連接。
  • way (Ways):處理控制台 UI,`welcome_wind()` 顯示主菜單,`input_id_pwd_wind()` 獲取帳號密碼。
  • 角色指針:延遲創建,登錄成功後 `new` 對應角色對象,實現權限分離。

核心流程:Lib_Run 登錄驗證邏輯


void Lib_Run(int i=3) {
    MYSQL_RES *point;
    while (i != 0) {                    // 循環直到用戶選擇退出 (i=0)
        i = way->welcome_wind();        // 1. 顯示菜單,獲取用戶選項 (1=登錄, 0=退出)
        if (i == 1) {
            way->input_id_pwd_wind();   // 2. 提示輸入帳號密碼
            string id, id1, pwd;
            cin >> id >> pwd;           // 3. 讀取輸入
            
            // 4. 構建查詢 SQL:查詢該管理員密碼、姓名、職位
            id1 = "SELECT manage_pwd, manage_name, manage_position FROM manager WHERE manage_id = '" + id + "';";
            
            // 5. 驗證密碼(列索引 0)
            se.Demand_str_one(id1.c_str(), 0, 0);
            if (pwd == string(se.data)) { // 密碼匹配
                // 6. 獲取姓名(列 1)
                se.Demand_str_one(id1.c_str(), 0, 1);
                string name(se.data);
                // 7. 獲取職位(列 2)
                se.Demand_str_one(id1.c_str(), 0, 2);
                string position(se.data);
                
                // 8. 角色分發
                if (position == "超級管理員") {
                    cout << "歡迎你超級管理員" << name << endl;
                    sumanag = new SuManager(id, pwd, name, position); // 創建超管對象
                    // 進入超管子菜單...
                } else if (position == "管理員") {
                    // 類似創建 Manager 對象...
                }
            } else {
                cout << "密碼錯誤!" << endl;
            }
        }
    }
}

關鍵技術點詳解

1. Chaxun::Demand_str_one 參數含義


// 推測簽名:void Demand_str_one(const char* sql, int row, int col);
// 執行 SQL,定位到第 row 行、第 col 列,將結果存入成员变量 data (char* 或 string)

2. SQL 注入風險

代碼直接拼接 `id` 進 SQL:`... WHERE manage_id = '" + id + "'`。極其危險,需改用預處理語句:


// 使用 MYSQL_STMT 參數綁定
MYSQL_STMT *stmt = mysql_stmt_init(se.conn);
const char *query = "SELECT manage_pwd, manage_name, manage_position FROM manager WHERE manage_id = ?";
mysql_stmt_prepare(stmt, query, strlen(query));
// 綁定 id 參數執行...

3. 內存管理缺陷

  • `sumanag = new SuManager(...)` 但析構函數 `~Libary(){}` 未 `delete`,會內存洩漏。
  • 建議改用 `std::unique_ptr sumanag;` 自動管理。

4. 硬編碼配置

構造函數默認值 `root/root/test/3306` 懹提取至配置文件(INI/JSON/YAML),啟動時讀取。

類圖關係梳理

Libary (控制器)
├── Chaxun se (數據訪問層 DAO)
├── Ways *way (視圖層 View)
├── Manager *manager (業務實體)
├── Reader *read
└── SuManager *sumanag

重構建議

  1. **分層**:DAO (Chaxun) / Service (Manager/Reader) / Controller (Libary) / View (Ways)。
  2. **安全**:預處理語句防注入,密碼加密存儲(BCrypt)。
  3. **資源**:智能指針管理對象生命周期,RAII 管理 MySQL 連接。
  4. **配置**:外部化數據庫連接參數。
  5. **擴展**:引入角色權限體系(RBAC),替代硬編碼 `if (position == ...)`。

總結

`Libary` 類展示了典型的 C++ 控制台管理系統架構:主循環 + 菜單驅動 + 角色分發 + 數據庫交互。理解其構造注入、登錄驗證流程、依賴關係,是掌握該系統擴展維護的關鍵。但需嚴正修復 SQL 注入、內存洩漏、硬編碼等生產級缺陷。

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