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

C++ 單鏈表模板類 simplelist.h 深度解析與常見錯誤修正

     編輯:程式設計綜合問答

代碼結構概覽

提供的 `simplelist.h` 是一個**帶頭結點的單鏈表模板類**實現,包含:

  • 節點結構 `LinkNode`:數據域 `data`、指針域 `link`
  • 列表類 `List`:頭指針 `first`、構造/拷貝/析構、插入/刪除/查找/遍歷/賦值等核心操作
  • 主函數演示:鍵盤輸入建表、拷貝構造、輸出驗證

關鍵缺陷與修正

問題原代碼修正方案
頭文件守衛宏名錯誤 `#if !defined_LIST_H_` / `#define _LIST_H` 統一宏名:`#ifndef SIMPLELIST_H` / `#define SIMPLELIST_H`
缺少必要頭文件 無 `#include <iostream>` 等 添加 ``, ``, `` (C++11)
模板成員函數定義需在頭文件 分離聲明/定義導致鏈接錯誤 全部實現放在 `.h` 中,或 `.tpp` 包含在 `.h` 尾部
`output()` 方法語法錯誤 `cout<data<` `std::cout << current->data << ' ';`
`inputFront` 拼寫不一致 聲明 `inputFrond` / 定義 `inputFront` / 調用 `inputFrond` 統一為 `inputFront` (前插法)
拷貝構造/賦值運算符異常安全 先 `new LinkNode` 再拷貝,中途拋異常洩漏 採用 Copy-and-Swap 慣用語或智能指針 `std::unique_ptr`
缺少 `const` 正確性 多處只讀方法未標 `const` 檢查所有不修改狀態的方法加 `const`
主函數 `cout l1.inputFrond(-1);` 語法錯誤 `cout<<...< cout l1.inputFrond(-1);` 分兩句:`std::cout << "提示..."; l1.inputFront(-1);`

現代化重寫版 (C++17 風格)

#ifndef SIMPLELIST_H
#define SIMPLELIST_H

#include 
#include 
#include 
#include 

template 
class List {
    struct Node {
        T data;
        std::unique_ptr next;
        Node(const T& d, std::unique_ptr&& n = nullptr) : data(d), next(std::move(n)) {}
    };
    std::unique_ptr head = std::make_unique(T{}); // 哨兵節點

public:
    List() = default;
    List(const List& other) { copyFrom(other); }
    List& operator=(List other) { swap(other); return *this; } // Copy-and-Swap
    ~List() = default; // unique_ptr 自動釋放

    void push_front(const T& val) {
        head->next = std::make_unique(val, std::move(head->next));
    }

    void print() const {
        for (Node* p = head->next.get(); p; p = p->next.get())
            std::cout << p->data << ' ';
        std::cout << '\n';
    }

    // 迭代器支持範圍 for
    struct Iterator {
        Node* ptr;
        T& operator*() { return ptr->data; }
        Iterator& operator++() { ptr = ptr->next.get(); return *this; }
        bool operator!=(const Iterator& o) const { return ptr != o.ptr; }
    };
    Iterator begin() { return {head->next.get()}; }
    Iterator end() { return {nullptr}; }

private:
    void copyFrom(const List& other) {
        Node* src = other.head->next.get();
        Node** dst = &head->next;
        while (src) {
            *dst = std::make_unique(src->data);
            dst = &(*dst)->next;
            src = src->next.get();
        }
    }
    void swap(List& other) noexcept { head.swap(other.head); }
};

#endif // SIMPLELIST_H

使用示例

#include "simplelist.h"
int main() {
    List lst;
    std::cout << "輸入整數以 -1 結束: ";
    int x;
    while (std::cin >> x && x != -1) lst.push_front(x);
    
    std::cout << "列表內容: ";
    lst.print(); // 或 for (auto v : lst) std::cout << v << ' ';
    
    List lst2 = lst; // 拷貝構造
    std::cout << "拷貝後: ";
    lst2.print();
}

學習建議

  1. 先理解**帶頭結點單鏈表**的指針操作邏輯(插入/刪除/查找圖解)。
  2. 掌握**模板類編譯模型**:聲明與定義不可分離,否則鏈接階段找不到實例化代碼。
  3. 學習 **Rule of Three/Five/Zero**:手動管理資源的類必須正確實現拷貝/移動/析構。
  4. 實踐中優先使用 `std::list` / `std::forward_list` (C++11),僅在教學/面試/嵌入式無 STL 環境手寫。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved