刚开始我是震惊的!
我从未想过[]下居然有逻辑!
从接触程序设计语言开始
曾因会使用a[0]访问数组元素而沾沾自喜
曾认为[] ,理应是访问数组的一种方式
曾认为[]只是一个无情的标识!
所以
当我们写下a[0]时,究竟是为了什么?
是为了找到a[0]对应的值
那么如何能找到它对应的值?
首先要找到它对应的地址
这样只是能读取
如何能修改其值?(a[0]=5)
当然是返回左值引用
重载[]运算符有何应用场景?
可以像数组一样访问链表类
代码逻辑是怎样的?
index=0 指针不动 返回其数据域
index=1 指针指向下个节点 返回其数据域
如何确保指针不出界?
最后一个节点的指针域是nullptr 如果指针指向nullptr则表示到头了
是否应该考虑const重载?
应该!
cpp
#include <iostream>
#include <stdexcept>
template <typename T>
class LinkedList
{
private:
struct Node
{
T data; // 存储的数据
Node *next; // 指向下一个节点的指针
Node(T val, Node *ptr = nullptr) : data(val), next(ptr) {}
};
Node *head; // 链表的头节点
public:
LinkedList() : head(nullptr) {}
~LinkedList()
{
clear();
}
void add(T value)
{
// 在链表末尾添加元素
if (head == nullptr)
{
head = new Node(value);
}
else
{
Node *temp = head;
while (temp->next != nullptr)
{
temp = temp->next;
}
temp->next = new Node(value);
}
}
void clear()
{
// 清空链表,释放内存
Node *current = head;
while (current != nullptr)
{
Node *next = current->next;
delete current;
current = next;
}
head = nullptr;
}
T &operator[](int index)
{
// 重载[]运算符,以便可以使用索引访问元素
Node *temp = head;
int count = 0;
while (temp != nullptr && count < index)
{
temp = temp->next;
++count;
}
if (temp == nullptr)
{
throw std::out_of_range("Index out of range");
}
return temp->data; // 返回对应节点的数据引用
}
// 为了避免在const对象上使用[]运算符时出错,添加const版本的[]运算符
const T &operator[](int index) const
{
Node *temp = head;
int count = 0;
while (temp != nullptr && count < index)
{
temp = temp->next;
++count;
}
if (temp == nullptr)
{
throw std::out_of_range("Index out of range");
}
return temp->data;
}
};
int main()
{
LinkedList<int> list;
list.add(10);
list.add(20);
list.add(30);
// 访问和修改元素
std::cout << list[1] << std::endl; // 20
list[1] = 50;
std::cout << list[1] << std::endl; // 50
// 异常处理
try
{
list[3]; // 0 1 2 没有 3
}
catch (const std::out_of_range &e)
{
std::cout << e.what() << std::endl;
}
return 0;
}