mirror of
https://github.com/ChuXunYu/OnlineRpg.git
synced 2026-01-31 11:55:46 +00:00
194 lines
4.5 KiB
C++
194 lines
4.5 KiB
C++
#pragma once
|
|
#include <vector>
|
|
#include <stdexcept>
|
|
|
|
/**
|
|
* @brief 链表节点模板类
|
|
* @tparam T 节点存储的数据类型
|
|
*
|
|
* 技术点: 模板 (Template)
|
|
*/
|
|
template <typename T>
|
|
struct Node {
|
|
T data;
|
|
Node<T>* next;
|
|
|
|
explicit Node(const T& d) : data(d), next(nullptr) {}
|
|
};
|
|
|
|
/**
|
|
* @brief 历史日志记录器 - 使用模板和手写链表实现
|
|
* @tparam T 日志条目的数据类型
|
|
*
|
|
* 技术点:
|
|
* 1. 模板 (Template) - 泛型编程
|
|
* 2. 链表 (Linked List) - 手写数据结构
|
|
*
|
|
* 用途: 用于记录战斗日志,满足课程要求的"模板+链表"技术点
|
|
*/
|
|
template <typename T>
|
|
class HistoryLog {
|
|
private:
|
|
Node<T>* head; // 链表头指针
|
|
Node<T>* tail; // 链表尾指针 (用于快速追加)
|
|
int size; // 链表大小
|
|
|
|
public:
|
|
/**
|
|
* @brief 构造函数
|
|
*/
|
|
HistoryLog() : head(nullptr), tail(nullptr), size(0) {}
|
|
|
|
/**
|
|
* @brief 析构函数 - 必须正确释放所有节点内存
|
|
*/
|
|
~HistoryLog() {
|
|
clear();
|
|
}
|
|
|
|
/**
|
|
* @brief 拷贝构造函数 (深拷贝)
|
|
*/
|
|
HistoryLog(const HistoryLog& other) : head(nullptr), tail(nullptr), size(0) {
|
|
Node<T>* current = other.head;
|
|
while (current != nullptr) {
|
|
add(current->data);
|
|
current = current->next;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief 拷贝赋值运算符
|
|
*/
|
|
HistoryLog& operator=(const HistoryLog& other) {
|
|
if (this != &other) {
|
|
clear();
|
|
Node<T>* current = other.head;
|
|
while (current != nullptr) {
|
|
add(current->data);
|
|
current = current->next;
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* @brief 在链表尾部添加新的日志条目
|
|
* @param logEntry 日志条目
|
|
*/
|
|
void add(const T& logEntry) {
|
|
Node<T>* newNode = new Node<T>(logEntry);
|
|
|
|
if (head == nullptr) {
|
|
// 空链表
|
|
head = newNode;
|
|
tail = newNode;
|
|
} else {
|
|
// 追加到尾部
|
|
tail->next = newNode;
|
|
tail = newNode;
|
|
}
|
|
|
|
size++;
|
|
}
|
|
|
|
/**
|
|
* @brief 在链表头部插入日志条目
|
|
* @param logEntry 日志条目
|
|
*/
|
|
void addFront(const T& logEntry) {
|
|
Node<T>* newNode = new Node<T>(logEntry);
|
|
|
|
if (head == nullptr) {
|
|
head = newNode;
|
|
tail = newNode;
|
|
} else {
|
|
newNode->next = head;
|
|
head = newNode;
|
|
}
|
|
|
|
size++;
|
|
}
|
|
|
|
/**
|
|
* @brief 获取所有日志条目
|
|
* @return std::vector<T> 包含所有日志条目的向量
|
|
*/
|
|
std::vector<T> getAllEntries() const {
|
|
std::vector<T> entries;
|
|
entries.reserve(size);
|
|
|
|
Node<T>* current = head;
|
|
while (current != nullptr) {
|
|
entries.push_back(current->data);
|
|
current = current->next;
|
|
}
|
|
|
|
return entries;
|
|
}
|
|
|
|
/**
|
|
* @brief 获取链表大小
|
|
* @return int 日志条目数量
|
|
*/
|
|
int getSize() const {
|
|
return size;
|
|
}
|
|
|
|
/**
|
|
* @brief 检查链表是否为空
|
|
* @return bool true 如果为空
|
|
*/
|
|
bool isEmpty() const {
|
|
return size == 0;
|
|
}
|
|
|
|
/**
|
|
* @brief 清空所有日志条目
|
|
*/
|
|
void clear() {
|
|
Node<T>* current = head;
|
|
while (current != nullptr) {
|
|
Node<T>* temp = current;
|
|
current = current->next;
|
|
delete temp;
|
|
}
|
|
head = nullptr;
|
|
tail = nullptr;
|
|
size = 0;
|
|
}
|
|
|
|
/**
|
|
* @brief 获取指定索引的日志条目
|
|
* @param index 索引 (0-based)
|
|
* @return const T& 日志条目的引用
|
|
* @throw std::out_of_range 如果索引超出范围
|
|
*/
|
|
const T& at(int index) const {
|
|
if (index < 0 || index >= size) {
|
|
throw std::out_of_range("Index out of range");
|
|
}
|
|
|
|
Node<T>* current = head;
|
|
for (int i = 0; i < index; i++) {
|
|
current = current->next;
|
|
}
|
|
|
|
return current->data;
|
|
}
|
|
|
|
/**
|
|
* @brief 打印所有日志 (仅用于调试)
|
|
*/
|
|
void print() const {
|
|
Node<T>* current = head;
|
|
int index = 0;
|
|
while (current != nullptr) {
|
|
// 这里假设 T 支持 << 运算符
|
|
// std::cout << "[" << index++ << "] " << current->data << std::endl;
|
|
current = current->next;
|
|
index++;
|
|
}
|
|
}
|
|
};
|