C++学习之路,从0到精通的征途:List类的模拟实现
目录
一.list的介绍
二.list的接口实现
1.结点
2.list结构
3.迭代器
(1)begin
(2)end
4.修改
(1)insert
(2)push_back
(3)push_front
(4)erase
(5)pop_back
(6)pop_front
(7)swap
(8)clear
5.默认成员函数
(1)构造函数
(2)拷贝构造函数
(3)赋值重载
(4)析构函数
三.代码总览
list.h
test.cpp
一.list的介绍
源文档
二.list的接口实现
1.结点
template
struct list_node
{
list_node* _prev;
list_node* _next;
T _data;
// 由于数据类型由模板参数决定,所以缺省值给匿名对象
list_node(const T& x = T())
:_prev(nullptr)
,_next(nullptr)
,_data(x)
{}
};
用一个结构体来封装结点,我们手动写默认构造函数以便在申请结点时调用。
2.list结构
template
class list
{
// 结点
typedef list_node Node;
public:
// 在类域外访问
// 迭代器
typedef list_iterator iterator;
typedef list_iterator const_iterator;
private:
// 哨兵位
Node* _head;
// 有效数据个数
size_t _size = 0;
};
3.迭代器
list的迭代器与之前的string和vector不同,由于list的数据存储空间并不是连续的,所以我们无法再继续用原生指针来实现迭代器类型,++,解引用等操作并不能实现想要达到的目的,所以我们需要重载这些操作符,并将迭代器封装成一个新的类。
template
struct list_iterator
{
typedef list_node Node;
typedef list_iterator Self;
Node* _node; // 迭代器所指向的结点
list_iterator(Node* node)
:_node(node)
{}
// 比较指向的结点是否相同
bool operator!=(const Self& s)
{
return _node != s._node;
}
bool operator==(const Self& s)
{
return _node == s._node;
}
// Ref来控制iterator与const_iterator
// Ref->T& -- iterator;
// Ref->const T& -- const_iterator;
// 获取结点存储的数据
Ref operator*()
{
return _node->_data;
}
// 使迭代器指向下一个结点
Self& operator++()
{
_node = _node->_next;
return *this;
}
// 后置++
Self operator++(int)
{
Self tmp(*this);
_node = _node->_next;
return tmp;
}
// 使迭代器指向前一个结点
Self& operator--()
{
_node = _node->_prev;
return *this;
}
// 前置--
Self operator--(int)
{
Self tmp(*this);
_node = _node->_prev;
return tmp;
}
// 为了可读性进行特殊处理 it->->_a1 被优化为 it->_a1
// Ptr来控制iterator与const_iterator
// Ptr->T* -- iterator
// Ptr->const T* -- const_iterator
Ptr operator->()
{
return &_node->_data;
}
};
(1)begin
iterator begin()
{
return iterator(_head->_next);
}
const_iterator begin() const
{
return const_iterator(_head->_next);
}
(2)end
iterator end()
{
// 返回尾结点的下一个结点,也就是哨兵位
return iterator(_head);
}
const_iterator begin() const
{
return const_iterator(_head->_next);
}
4.修改
(1)insert
void insert(iterator pos, const T& x)
{
// 申请新结点的空间,调用构造
Node* newnode = new Node(x);
// 断开旧连接,连接新结点
Node* cur = pos._node;
Node* prev = cur->_prev;
// prev newnode cur
newnode->_prev = prev;
newnode->_next = cur;
prev->_next = newnode;
cur->_prev = newnode;
++_size;
}
(2)push_back
void push_back(const T& x)
{
//Node* newnode = new Node(x);
//Node* tail = _head->_prev;
tail newnode _head
//newnode->_prev = tail;
//newnode->_next = _head;
//tail->_next = newnode;
//_head->_prev = newnode;
insert(end(), x);
}
(3)push_front
void push_front(const T& x)
{
insert(begin(), x);
}
(4)erase
iterator erase(iterator pos)
{
Node* cur = pos._node;
Node* prev = cur->_prev;
Node* next = cur->_next;
prev->_next = next;
next->_prev = prev;
delete cur;
--_size;
//return iterator(next);
// 为防止迭代器失效,返回删除后的下一个结点的迭代器
// 单参数构造函数支持隐式转换
return next;
}
为防止erase后,pos依然指向被delete的结点从而导致迭代器失效,erase返回指向下一个结点的迭代器。
(5)pop_back
void pop_back()
{
erase(--end());
}
(6)pop_front
void pop_front()
{
erase(begin());
}
(7)swap
void swap(list& lt)
{
std::swap(_head, lt._head);
std::swap(_size, lt._size);
}
交换哨兵位即可交换两个list。
(8)clear
void clear()
{
auto it = begin();
while (it != end())
{
it = erase(it);
}
}
除了哨兵位,其他结点逐个erase。
5.默认成员函数
(1)构造函数
空list申请哨兵位:empty_init
// 空list申请哨兵位
void empty_init()
{
_head = new Node;
_head->_prev = _head;
_head->_next = _head;
}
// 无参数构造
list()
{
//_head = new Node;
//_head->_prev = _head;
//_head->_next = _head;
empty_init();
}
// initializer_list构造
list(std::initializer_list il)
{
empty_init();
for (auto& e : il)
{
push_back(e);
}
}
(2)拷贝构造函数
list(const list& lt)
{
empty_init();
for (auto& e : lt)
{
push_back(e);
}
}
先申请哨兵位,再逐个尾插即可。
(3)赋值重载
list& operator=(list lt)
{
swap(lt);
return *this;
}
(4)析构函数
~list()
{
clear();
delete _head;
_head = nullptr;
}
三.代码总览
list.h
#include
#include
namespace my_list
{
template
struct list_node
{
list_node* _prev;
list_node* _next;
T _data;
// 由于数据类型由模板参数决定,所以缺省值给匿名对象
list_node(const T& x = T())
:_prev(nullptr)
,_next(nullptr)
,_data(x)
{}
};
template
struct list_iterator
{
typedef list_node Node;
typedef list_iterator Self;
Node* _node; // 迭代器所指向的结点
list_iterator(Node* node)
:_node(node)
{}
// 比较指向的结点是否相同
bool operator!=(const Self& s)
{
return _node != s._node;
}
bool operator==(const Self& s)
{
return _node == s._node;
}
// Ref来控制iterator与const_iterator
// Ref->T& -- iterator;
// Ref->const T& -- const_iterator;
// 获取结点存储的数据
Ref operator*()
{
return _node->_data;
}
// 使迭代器指向下一个结点
Self& operator++()
{
_node = _node->_next;
return *this;
}
// 后置++
Self operator++(int)
{
Self tmp(*this);
_node = _node->_next;
return tmp;
}
// 使迭代器指向前一个结点
Self& operator--()
{
_node = _node->_prev;
return *this;
}
// 前置--
Self operator--(int)
{
Self tmp(*this);
_node = _node->_prev;
return tmp;
}
// 为了可读性进行特殊处理 it->->_a1 被优化为 it->_a1
// Ptr来控制iterator与const_iterator
// Ptr->T* -- iterator
// Ptr->const T* -- const_iterator
Ptr operator->()
{
return &_node->_data;
}
};
template
class list
{
// 结点
typedef list_node Node;
public:
// 迭代器
typedef list_iterator iterator;
typedef list_iterator const_iterator;
// 空list申请哨兵位
void empty_init()
{
_head = new Node;
_head->_prev = _head;
_head->_next = _head;
}
// 无参数构造
list()
{
//_head = new Node;
//_head->_prev = _head;
//_head->_next = _head;
empty_init();
}
// initializer_list构造
list(std::initializer_list il)
{
empty_init();
for (auto& e : il)
{
push_back(e);
}
}
list(const list& lt)
{
empty_init();
for (auto& e : lt)
{
push_back(e);
}
}
// lt2 = lt1
list& operator=(list lt)
{
swap(lt);
return *this;
}
~list()
{
clear();
delete _head;
_head = nullptr;
}
void clear()
{
auto it = begin();
while (it != end())
{
it = erase(it);
}
}
void swap(list& lt)
{
std::swap(_head, lt._head);
std::swap(_size, lt._size);
}
size_t size()
{
return _size;
}
iterator begin()
{
return iterator(_head->_next);
}
iterator end()
{
// 返回尾结点的下一个结点,也就是哨兵位
return iterator(_head);
}
const_iterator begin() const
{
return const_iterator(_head->_next);
}
const_iterator end() const
{
return const_iterator(_head);
}
void push_back(const T& x)
{
//Node* newnode = new Node(x);
//Node* tail = _head->_prev;
tail newnode _head
//newnode->_prev = tail;
//newnode->_next = _head;
//tail->_next = newnode;
//_head->_prev = newnode;
insert(end(), x);
}
void push_front(const T& x)
{
insert(begin(), x);
}
void pop_back()
{
erase(--end());
}
void pop_front()
{
erase(begin());
}
void insert(iterator pos, const T& x)
{
// 申请新结点的空间,调用构造
Node* newnode = new Node(x);
// 断开旧连接,连接新结点
Node* cur = pos._node;
Node* prev = cur->_prev;
// prev newnode cur
newnode->_prev = prev;
newnode->_next = cur;
prev->_next = newnode;
cur->_prev = newnode;
++_size;
}
iterator erase(iterator pos)
{
Node* cur = pos._node;
Node* prev = cur->_prev;
Node* next = cur->_next;
prev->_next = next;
next->_prev = prev;
delete cur;
--_size;
//return iterator(next);
// 为防止迭代器失效,返回删除后的下一个结点的迭代器
// 单参数构造函数支持隐式转换
return next;
}
private:
// 哨兵位
Node* _head;
// 有效数据个数
size_t _size = 0;
};
}
test.cpp
#include"list.h"
using namespace std;
namespace my_list
{
void test_list1()
{
list lt1;
lt1.push_back(1);
lt1.push_back(2);
lt1.push_back(3);
lt1.push_back(4);
list::iterator it = lt1.begin();
while (it != lt1.end())
{
*it += 10;
cout << *it << " ";
++it;
}
cout << endl;
lt1.push_back(1);
lt1.push_back(2);
lt1.push_front(3);
lt1.push_front(4);
for (auto& e : lt1)
{
cout << e << " ";
}
cout << endl;
lt1.pop_back();
lt1.pop_front();
for (auto& e : lt1)
{
cout << e << " ";
}
cout << endl;
cout << lt1.size() << endl;
}
void test_list2()
{
list lt1;
lt1.push_back(1);
lt1.push_back(2);
lt1.push_front(3);
lt1.push_front(4);
for (auto& e : lt1)
{
cout << e << " ";
}
cout << endl;
list lt2(lt1);
for (auto& e : lt1)
{
cout << e << " ";
}
cout << endl;
list lt3;
lt3 = lt1;
for (auto& e : lt1)
{
cout << e << " ";
}
}
struct AA
{
int _a1;
int _a2;
AA(int a1 = 1, int a2 = 1)
:_a1(a1)
, _a2(a2)
{}
};
void test_list3()
{
list lt1 = { 1,2,3,4 };
for (auto& e : lt1)
{
cout << e << " ";
}
cout << endl;
list lt2 = { {1,1},{2,2},{3,3},{4,4} };
list::iterator it = lt2.begin();
while (it != lt2.end())
{
//cout << (*it)._a1 << ":" << (*it)._a2 << endl;
//cout << it->->_a1 << ":" << it->->_a2 << endl;
cout << it->_a1 << ":" << it->_a2 << endl;
++it;
}
list::iterator lit = lt2.begin();
while (lit != lt2.end())
{
cout << lit.operator->()->_a1 << ":" << lit.operator->()->_a2 << endl;
++lit;
}
}
}
int main()
{
my_list::test_list3();
return 0;
}
本文地址:https://www.vps345.com/10122.html