1 Star 0 Fork 0

坤坤/c++入门代码及笔记

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
List.h 5.85 KB
一键复制 编辑 原始数据 按行查看 历史
坤坤 提交于 2025-06-01 23:37 +08:00 . 结构体实现多态.exe
#pragma once
#include<assert.h>
#include<iostream>
using namespace std;
namespace My_list {
template<class T>//模板声明
struct ListNode {//定义一个模板类,c++的结构体和类型相似
ListNode<T>* _next;
ListNode<T>* _prev;
T data;
ListNode(const T& x=T())//默认构造函数,T() 使用匿名对象调用构造函数做缺省值,
//内置类型也支持匿名对象拷贝构造
:_next(nullptr)
,_prev(nullptr)
,data(x)
{}
};
//多参数模板来区分iterator和const_iterator,根据参数类型不同生成编译器会生成不同的iterator
template<class T,class Ref,class Ptr>
struct List_iterator//定义一个迭代器类获取节点的地址
{
typedef ListNode<T> Node;
typedef List_iterator<T, Ref, Ptr> Self;//模板类重定义
Node* _node;
List_iterator(Node* node)
:_node(node)
{
//cout << "List_iterator(Node*& node)" << endl;
}
//List_iterator(const List_iterator<T>& it)//如果拷贝构造函数没有被调用,可能是因为编译器进行了优化(如返回值优化,RVO),直接构造了 it 对象,而没有通过临时对象进行拷贝构造。
// //现代编译器通常会进行这种优化,以减少不必要的拷贝操作。
//{
// _node = it._node;
// cout << "List_iterator(const List_iterator& it)" << endl;
//}
Ref operator*()
{
return _node->data;
}
Self& operator++()//运算符重载对节点的地址做处理,前置++
{
_node=_node->_next;
return *this;
}
Self operator++(int)//运算符重载对节点的地址做处理,后置++
{
Self temp = *this;//构造临时的iterator对象,调用了构造拷贝
_node = _node->_next;
return temp;
}
Self& operator--()//运算符重载对节点的地址做处理,前置--
{
_node = _node->_prev;
return *this;
}
Self operator--(int)//运算符重载对节点的地址做处理,后置++
{
Self temp = *this;//构造临时的iterator对象,调用了构造拷贝
_node = _node->_prev;
return temp;
}
bool operator!=(const Self& it)
{
return _node != it._node;
}
bool operator==(const Self& it)
{
return _node == it._node;
}
Ptr operator->()//->单目操作符,对于节点的数据为自定义类型,返回节点的数据的指针
{
return &_node->data;
}
};
//const_iterator
//template<class T>
//struct List_const_iterator//定义一个迭代器类获取节点的地址
//{
// typedef ListNode<T> Node;
// Node* _node;
// List_const_iterator(Node*& node)
// :_node(node)
// {
// cout << "List_const_iterator(Node * &node)" << endl;
// }
// //List_iterator(const List_iterator<T>& it)//如果拷贝构造函数没有被调用,可能是因为编译器进行了优化(如返回值优化,RVO),直接构造了 it 对象,而没有通过临时对象进行拷贝构造。
// // //现代编译器通常会进行这种优化,以减少不必要的拷贝操作。
// //{
// // _node = it._node;
// // cout << "List_iterator(const List_iterator& it)" << endl;
// //}
// const T& operator*()
// {
// return _node->data;
// }
// List_const_iterator<T>& operator++() //运算符重载对节点的地址做处理
// {
// _node = _node->_next;
// return *this;
// }
// bool operator!=(const List_const_iterator<T>& it)
// {
// return _node != it._node;
// }
// bool operator==(const List_const_iterator<T>& it)
// {
// return _node == it._node;
// }
// const T* operator->()//->单目操作符,对于节点的数据为自定义类型,返回节点的数据的指针
// {
// return &_node->data;
// }
//};
template<class T>
class list {
typedef ListNode<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;//new自定义类型,自定义类型会调用默认构造函数
_head->_prev = _head;
_head->_next = _head;
_size = 0;
}
list()
{
empty_init();
}
list(list<T>& lt)//深拷贝
{
empty_init();
for (auto & e : lt) {
push_back(e);
}
}
~list()
{
clear();
delete _head;
_head = nullptr;
}
//赋值运算符重载,利用深拷贝创建一个临时对象,再交换临时对象的头指针和大小,
//临时对象销毁会调用析构函数释放原来对象的空间
list<T>& operator = (list<T> lt)
{
swap(lt);
return *this;
}
void swap(list<T>& lt)
{
std::swap(_head,lt._head);
std::swap(_size, lt._size);
}
//花括号列表初始化
list(initializer_list <T> lt) {
empty_init();
for (auto& e : lt) {
push_back(e);
}
}
void clear()
{
iterator it = begin();
while (it != end()) {
it = erase(it);//更新迭代器
}
}
void push_back(const T& x)
{
/* Node* newnode = new Node(x);
newnode->_prev = _head->_prev;
_head->_prev->_next = newnode;
newnode->_next = _head;
_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());
}
size_t size()const
{
return _size;
}
void insert(iterator pos,const T& x)
{
Node* newnode = new Node(x);
pos._node->_prev->_next = newnode;
newnode->_prev = pos._node->_prev;
//pos._node->_prev->_next = newnode;
//newnode->_prev=pos._node->_prev;
newnode->_next = pos._node;
pos._node->_prev = newnode;
_size++;
}
iterator erase(iterator pos)
{
assert(pos!= end());
Node* cur = pos._node;
Node* curnext = cur->_next;
Node* curprev = cur->_prev;
curnext->_prev = curprev;
curprev->_next = curnext;
delete cur;
_size--;
return iterator(curnext);//返回删除节点的下一个位置,更新迭代器,防止迭代器失效
}
iterator begin()
{
return iterator(_head->_next);
}
//cosnt 函数重载不能通过返回值类型区分
/*
* 常量成员函数:在成员函数后面加上const关键字,表示该函数不会修改类的成员变量。
编译器会确保在常量成员函数中不会对类的任何非静态成员变量进行修改。
调用对象为常量对象:只有常量对象(即被const修饰的对象)才能调用常量成员函数。
如果一个对象被声明为const,那么它只能调用const成员函数。
函数签名的一部分:const是函数签名的一部分,因此可以用于函数重载。
例如,可以同时定义一个const版本和一个非const版本的成员函数。
*/
const_iterator cbegin()
{
return const_iterator(_head->_next);
}
iterator end()
{
return iterator(_head);
}
//const
const_iterator cend()
{
return const_iterator(_head);
}
private:
Node* _head;
size_t _size;
};
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/cxk_5555hhh/c-beginner-code-and-notes.git
git@gitee.com:cxk_5555hhh/c-beginner-code-and-notes.git
cxk_5555hhh
c-beginner-code-and-notes
c++入门代码及笔记
master

搜索帮助