C++ – 使用模板和智能指针构建一个双向链表工具类
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:C++ – 使用模板和智能指针构建一个双向链表工具类
原文链接:https://www.stubbornhuang.com/2145/
发布于:2022年05月31日 15:24:13
修改于:2022年05月31日 15:48:00

1 C++使用模板和智能指针构建一个双向链表工具类
本文使用模板和智能指针构建一个双向链表工具模板类DoubleLinkedList<T>
,在链表的节点Node
内部使用T用于接受模板参数,当前节点的上一个节点使用std::shared_ptr
,为防止节点与节点之间的std::shared_ptr
循环引用问题,避免造成内存泄漏,当前节点的下一个节点使用std::weak_ptr
,具体的代码如下文所示。
1.1 双向链表工具类
DoubleLinkedList.h
#ifndef DOUBLE_LINKED_LIST_H_
#define DOUBLE_LINKED_LIST_H_
#include <vector>
#include <memory>
#include <iostream>
template<typename T>
struct Node {
explicit Node(T val)
: value{ val }
{}
~Node() {
std::cout << "Node " << value << " destroyed\n";
}
Node(const Node&) = default;
Node(Node&&) = default;
Node& operator=(const Node&) = default;
Node& operator=(Node&&) = default;
T value;
std::shared_ptr<Node> next = nullptr;
std::weak_ptr<Node> previous; // 使用std::weak_ptr防止std::shared_ptr循环引用,避免内存泄漏
};
template<typename T>
class DoubleLinkedList {
public:
void PushFront(T x);
void PushBack(T x);
std::vector<T> GetNodesForward();
std::vector<T> GetNodesReverse();
private:
std::shared_ptr<Node<T>> front = nullptr;
std::shared_ptr<Node<T>> back = nullptr;
};
template<typename T>
void DoubleLinkedList<T>::PushFront(T x)
{
const auto n = std::make_shared<Node<T>>(x);
if (not front) {
front = n;
back = n;
}
else {
front->previous = n;
n->next = front;
front = n;
}
}
template<typename T>
void DoubleLinkedList<T>::PushBack(T x)
{
const auto n = std::make_shared<Node<T>>(x);
if (not back) {
front = n;
back = n;
}
else {
back->next = n;
n->previous = back;
back = n;
}
}
template<typename T>
std::vector<T> DoubleLinkedList<T>::GetNodesForward()
{
auto temp = front;
std::vector<T> out;
while (temp) {
out.push_back(temp->value);
temp = temp->next;
}
return out;
}
template<typename T>
std::vector<T> DoubleLinkedList<T>::GetNodesReverse()
{
auto temp = back;
std::vector<T> out;
while (temp) {
out.push_back(temp->value);
temp = temp->previous.lock();
}
return out;
}
#endif // !DOUBLE_LINKED_LIST_H_
1.2 双向链表工具类使用示例
#include <iostream>
#include "DoubleLinkedList.h"
class Animal
{
public:
Animal()
:m_Age(0)
{
}
Animal(int age)
:m_Age(age)
{
}
virtual~Animal()
{
}
void SetAge(int age)
{
m_Age = age;
}
int GetAge()
{
return m_Age;
}
private:
int m_Age;
};
template<typename T>
void PrintVectorDouble(const std::vector<T>& vec)
{
for (int i = 0; i < vec.size(); ++i)
{
std::cout << vec[i] << " ";
}
std::cout << std::endl;
}
template<typename T>
void PrintVectorClass(const std::vector<T>& vec)
{
for (int i = 0; i < vec.size(); ++i)
{
std::cout << vec[i]->GetAge() << " ";
}
std::cout << std::endl;
}
int main()
{
// double
DoubleLinkedList<double> double_linked_list;
for (int i = 0; i < 4; ++i)
{
double_linked_list.PushFront(1.1 * i);
}
PrintVectorDouble(double_linked_list.GetNodesForward());
PrintVectorDouble(double_linked_list.GetNodesReverse());
for (int i = 0; i < 4; ++i)
{
double_linked_list.PushBack(1.1 * i);
}
PrintVectorDouble(double_linked_list.GetNodesForward());
PrintVectorDouble(double_linked_list.GetNodesReverse());
// Animal
DoubleLinkedList<std::shared_ptr<Animal>> animal_linked_list;
for (int i = 0; i < 4; ++i)
{
animal_linked_list.PushFront(std::make_shared<Animal>(i));
}
PrintVectorClass(animal_linked_list.GetNodesForward());
PrintVectorClass(animal_linked_list.GetNodesReverse());
for (int i = 0; i < 4; ++i)
{
animal_linked_list.PushBack(std::make_shared<Animal>(i));
}
PrintVectorClass(animal_linked_list.GetNodesForward());
PrintVectorClass(animal_linked_list.GetNodesReverse());
return 0;
}
结果输出
3.3 2.2 1.1 0
0 1.1 2.2 3.3
3.3 2.2 1.1 0 0 1.1 2.2 3.3
3.3 2.2 1.1 0 0 1.1 2.2 3.3
3 2 1 0
0 1 2 3
3 2 1 0 0 1 2 3
3 2 1 0 0 1 2 3
Node 00000000004F9060 destroyed
Node 00000000004F9000 destroyed
Node 00000000004F8FA0 destroyed
Node 00000000004F8F40 destroyed
Node 00000000004F90C0 destroyed
Node 00000000004F9120 destroyed
Node 00000000004F9180 destroyed
Node 00000000004F91E0 destroyed
Node 3.3 destroyed
Node 2.2 destroyed
Node 1.1 destroyed
Node 0 destroyed
Node 0 destroyed
Node 1.1 destroyed
Node 2.2 destroyed
Node 3.3 destroyed
参考链接
当前分类随机文章推荐
- Centos7 编译C++项目错误解决 : terminate called after throwing an instance of 'std::regex_error' 阅读2445次,点赞1次
- C++ - 将一维数组/二维数组/三维数组作为函数参数传递给函数 阅读1406次,点赞0次
- C++STL容器 - std::map删除指定元素 阅读1742次,点赞0次
- C++ - 函数返回多个返回值的方法总结 阅读1706次,点赞0次
- C++ - 导出接口函数和导出C++类 阅读220次,点赞0次
- C++ - 动态链接库dll为什么要使用unsigned char作为byte的内部格式 阅读620次,点赞0次
- C++ - 得到字符串中某个字符串出现的个数 阅读3860次,点赞2次
- C++ - std::numeric_limits
简介与使用,用于获取指定数据类型的最大值与最小值 阅读229次,点赞0次 - C++ - vector存储动态指针时正确释放内存 阅读5591次,点赞0次
- C++11/std::atomic - 原子变量(不加锁实现线程互斥) 阅读6144次,点赞2次
全站随机文章推荐
- 资源分享 - WebGL Programming Guide - Interactive 3D Graphics Programming with WebGL 英文高清PDF下载 阅读1320次,点赞0次
- 资源分享 - Computational Geometry - Algorithms and Applications, Third Edition 英文高清pdf下载 阅读5367次,点赞1次
- 深度学习 - 动作识别Action Recognition最重要的问题 阅读323次,点赞1次
- 深度学习 - 数据集中训练集、验证集、测试集的划分以及各自作用 阅读1967次,点赞0次
- 资源分享 - Essential Mathematics for Games and Interactive Applications(Third Edition) 英文高清PDF下载 阅读1837次,点赞0次
- 资源分享 - 解读基金:我的投资观与实践(季凯帆,康峰著)PDF下载 阅读1458次,点赞0次
- 资源分享 - Foundations of Physically Based Modeling and Animation 英文PDF下载 阅读3530次,点赞0次
- 我的开源项目 - 各种搜索引擎收录查询接口(Google/百度/必应/360/搜狗......) 阅读4161次,点赞3次
- C++ - 得到字符串中某个字符串出现的个数 阅读3860次,点赞2次
- Visual Studio - 借助远程Linux服务器环境在Visual Studio中编写和远程调试Linux C++程序 阅读1058次,点赞0次
评论
168