hello~ 很高兴见到大家! 这次带来的是C++中关于list容器这部分的一些知识点,如果对你有所帮助的话,可否留下你的三连呢? 个 人 主 页: 默|笙

接上次的博客<list的使用>
由于模板的特殊,声明和定义不分离,即把它们放在一个文件里(.h)。
模板的实例化需要看到完整定义,而分文件编译机制导致无法让编译器在使用模板的地方获取定义,导致无法生成实例代码,链接失败。
template<class T>
struct list_node//节点
{
T _data;
list_node<T>* _next;//指向前一个节点的指针
list_node<T>* _prev;//指向后一个节点的指针
list_node(const T& x = T())//构造节点
:_data(x)
,_next(nullptr)
,_prev(nullptr)
{}
}; 则有:
template<class T>
struct __list_iterator
{
typedef list_node<T> Node;
Node* _node;
__list_iterator(Node* node)
:_node(node)
{}
T& operator*()
{
return _node->_data;
}
//前置++
__list_iterator<T>& operator++()
{
_node = _node->_next;
return *this;
}
//后置++
__list_iterator<T> operator++(int)
{
__list_iterator<T> tmp(*this);
_node = _node->_next;
return tmp;
}
//前置--
__list_iterator<T>& operator--()
{
_node = _node->_prev;
return *this;
}
//后置--
__list_iterator<T> operator--(int)
{
__list_iterator<T> tmp(*this);
_node = _node->_prev;
return tmp;
}
//!=
bool operator!=(const __list_iterator<T>& it)const
{
return _node != it._node;
}
//==
bool operator==(const __list_iterator<T>& it)const
{
return _node == it._node;
}
};注:这里的 this 是迭代器指针,也就是__list_iterator*,而*this是迭代器。
迭代器这个类不需要实现析构函数,拷贝构造函数和赋值重载函数。前者是因为它没有资源需要释放,它只是目前指向/管理这个节点,这个节点并不属于它;后面两个是因为我们需要的就是浅拷贝,指向同一块空间,不需要进行深拷贝。
const T& operator*()
{
return _node->_data;
}接下来,我们来看一段加上常量迭代器过后的代码:
template<class T>
struct __list_iterator
{
typedef list_node<T> Node;
Node* _node;
__list_iterator(Node* node)
:_node(node)
{}
T& operator*()
{
return _node->_data;
}
//2
const T& operator*()
{
return _node->_data;
}
};
template<class T>
class list
{
typedef list_node<T> Node;
public:
typedef __list_iterator<T> iterator;
//1
typedef const __list_iterator<T> const_iterator;
private:
};这里省略了很多代码,留下了主要的部分。这个代码里存在着两处问题。
如下:
//普通迭代器
template<class T>
struct __list_iterator
{
typedef list_node<T> Node;
Node* _node;
__list_iterator(Node* node)
:_node(node)
{}
T& operator*()
{
return _node->_data;
}
//前置++
__list_iterator<T>& operator++()
{
_node = _node->_next;
return *this;
}
//后置++
__list_iterator<T> operator++(int)
{
__list_iterator<T> tmp(*this);
_node = _node->_next;
return tmp;
}
//前置--
__list_iterator<T>& operator--()
{
_node = _node->_prev;
return *this;
}
//后置--
__list_iterator<T> operator--(int)
{
__list_iterator<T> tmp(*this);
_node = _node->_prev;
return tmp;
}
//!=
bool operator!=(const __list_iterator<T>& it)const
{
return _node != it._node;
}
//==
bool operator==(const __list_iterator<T>& it)const
{
return _node == it._node;
}
};
//常量迭代器
template<class T>
struct __list_const_iterator
{
typedef list_node<T> Node;
Node* _node;
__list_iterator(Node* node)
:_node(node)
{}
const T& operator*()
{
return _node->_data;
}
//前置++
__list_iterator<T>& operator++()
{
_node = _node->_next;
return *this;
}
//后置++
__list_iterator<T> operator++(int)
{
__list_iterator<T> tmp(*this);
_node = _node->_next;
return tmp;
}
//前置--
__list_iterator<T>& operator--()
{
_node = _node->_prev;
return *this;
}
//后置--
__list_iterator<T> operator--(int)
{
__list_iterator<T> tmp(*this);
_node = _node->_prev;
return tmp;
}
//!=
bool operator!=(const __list_iterator<T>& it)const
{
return _node != it._node;
}
//==
bool operator==(const __list_iterator<T>& it)const
{
return _node == it._node;
}
};
template<class T>
class list
{
typedef list_node Node;
public:
typedef __list_iterator iterator;
//重命名常量迭代器
typedef __list_const_iterator const_iterator;
private:
};如下:
template<class T, class Ref>
struct __list_iterator
{
typedef list_node<T> Node;
typedef __list_iterator<T, Ref> Self;
Node* _node;
__list_iterator(Node* node)
:_node(node)
{}
//*重载
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;
}
//!=
bool operator!=(const Self& it)const
{
return _node != it._node;
}
//==
bool operator==(const Self& it)const
{
return _node == it._node;
}
};
template<class T>
class list
{
typedef list_node Node;
public:
typedef __list_iterator<T, T&> iterator;
typedef __list_iterator<T, const T&> const_iterator;
private:
};
接下来看一段代码:
//这是一个类:
struct Pos
{
int _row;
int _col;
Pos(int row = 0, int col = 0)
:_row(row)
, _col(col)
{}
};
//我们尝试打印一下存储这个Pos类型的list<Pos>,假设list已经实现
int main()
{
mosheng::list<Pos> lt1;
lt1.push_back({1,1});//隐式类型转换
lt1.push_back({2,2});
lt1.push_back({3,3});
lt1.push_back({4,4});
auto it = lt1.begin();
while (it != lt1.end())
{
//cout << (*it)._row << ":" << (*it)._col << endl;
cout << it->_row << ":" << it->_col << endl;
++it;
}
cout << endl;
return 0;
}

//operator->() 的返回类型必须是 T* 或迭代器,无论 T 是否为指针类型
T* operator->()
{
return &_node->_data;
}
template<class T, class Ref, class Ptr>
struct __list_iterator
{
typedef list_node<T> Node;
typedef __list_iterator<T, Ref, Ptr> Self;
Node* _node;
__list_iterator(Node* node)
:_node(node)
{}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &_node->_data;
}
}
class list
{
typedef list_node<T> Node;
public:
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
}
//省略中间一部分由于链表的实现比较简单没有什么需要单独拿出来讲的内容,这里就跳过了。
template<class T>
class list
{
typedef list_node<T> Node;
public:
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
//创造头节点函数
void empty_Init()
{
_head = new Node;
_head->_prev = _head;
_head->_next = _head;
}
//默认构造函数
list()
{
empty_Init();
}
//拷贝构造函数
list<T> (const list<T>& lt)
{
empty_Init();
for (const auto& e : lt)
{
push_back(e);
}
}
//初始化列表构造函数
list(initializer_list<T> il)
{
empty_Init();
for (const auto& e : il)
{
push_back(e);
}
}
//清除链表节点,留下头节点
void clear()
{
iterator it = begin();
while (it != end())
{
it = erase(it);
}
_size = 0;
}
//析构函数
~list()
{
clear();//清除所有节点
delete _head;//清除头节点
_head = nullptr;
}
//交换
void swap(list<T>& lt)
{
std::swap(_head, lt._head);
std::swap(_size, lt._size);
}
//赋值重载函数(现代写法)
list<T>& operator=(list lt)
{
swap(lt);
return *this;
}
//begin()
iterator begin()
{
return iterator(_head->_next);
}
const_iterator begin()const
{
return cosnt_iterator(_head->_next);
}
//end()
iterator end()
{
return iterator(_head);
}
const_iterator end()const
{
return const_iterator(_head);
}
//在指定位置插入
iterator insert(iterator pos, const T& x)
{
Node* cur = pos._node;
Node* newnode = new Node(x);
Node* prev = cur->_prev;
prev->_next = newnode;
newnode->_next = cur;
newnode->_prev = prev;
cur->_prev = newnode;
_size++;
return iterator(newnode);
}
//删除指定位置
iterator erase(iterator pos)
{
Node* cur = pos._node;
Node* next = cur->_next;
Node* prev = cur->_prev;
prev->_next = next;
next->_prev = prev;
delete cur;
cur = nullptr;
_size--;
return iterator(next);
}
//尾插
void push_back(const T& x)
{
insert(end(), x);
}
//头插
void push_front(const T& x)
{
insert(begin(), x);
}
//尾删
void pop_back()
{
erase(--end());
}
//头删
void pop_front()
{
erase(begin());
}
//节点个数
size_t size()
{
return _size;
}
private:
Node* _head;
size_t _size = 0;
};
}今天的分享就到此结束啦,如果对读者朋友们有所帮助的话,可否留下宝贵的三连呢~~ 如果可以, 那就让我们共同努力, 一起走下去!