C++之list類的代碼及其邏輯詳解 (中)

接下來我會依照前面所說的一些接口以及list的結構來進行講解。

1. list_node的結構

1.1 list_node結構體

list由于其結構為雙向循環鏈表,所以我們在這里要這么初始化

  • _next:指向鏈表中下一個節點的指針
  • _prev:指向鏈表中上一個節點的指針
  • _val:存儲節點的值

list_node(const T& val = T())?用于初始化節點,將?_next?和?_prev?指針默認設置為?nullptr,并將?_val?初始化為傳入的值

struct list_node
{list_node<T>* _next;list_node<T>* _prev;T _val;list_node(const T& val = T()):_next(nullptr), _prev(nullptr), _val(val){}
};
  1. typedef list_node<T> Node;

    • list_node<T>(鏈表節點類型)簡化定義為Node
    • 在類內部可以直接使用Node來表示鏈表節點類型,無需重復寫list_node<T>
  2. typedef _list_iterator<T, T&, T*> iterator;

    • 定義了普通迭代器類型iterator
    • 這里的_list_iterator應該是一個迭代器模板類,三個模板參數分別表示:
      • 存儲的數據類型T
      • 迭代器解引用后返回的引用類型T&
      • 迭代器解引用后返回的指針類型T*
  3. typedef _list_iterator<T, const T&, const T*> const_iterator;

    • 定義了常量迭代器類型const_iterator
    • 與普通迭代器的區別是,解引用后返回的是const類型的引用和指針
    • 用于對const list對象進行遍歷,保證不能通過迭代器修改元素值
class list
{public:typedef list_node<T> Node;typedef _list_iterator<T, T&, T*> iterator;typedef _list_iterator<T, const T&, const T*> const_iterator;
};

1.2?list和list_node分離設計原因?

list_node結構體和list類分離設計,是一種典型的 "數據存儲" 與 "邏輯管理" 分離的思想。

1.?職責分離,符合單一職責原則
  • list_node結構體:僅負責存儲單個節點的數據連接關系(前驅_prev、后繼_next指針),它的職責非常單一 —— 就是作為鏈表的 "最小數據單元"。
  • list:負責管理整個鏈表的邏輯,包括節點的創建 / 銷毀、插入 / 刪除、遍歷、容量管理等操作。它不直接存儲數據,而是通過操作list_node對象來實現鏈表的整體功能。

這種分離讓代碼更清晰:節點只關心自身數據和連接,鏈表類只關心整體邏輯,便于維護和擴展。

2.?封裝性更好,隱藏實現細節
  • list_node通常是list類的內部私有類型(或通過typedef限定在類內部使用),外部用戶不需要知道節點的具體結構(比如_prev_next指針的存在)。
  • 用戶只需通過list類提供的接口(如push_backerase、迭代器等)操作鏈表,無需直接接觸節點,避免了誤操作節點指針導致的內存問題(如野指針、內存泄漏)。
3.?便于迭代器設計和容器適配
  • 鏈表的迭代器需要通過節點的_next/_prev指針實現遍歷,將節點封裝為list_node后,迭代器可以統一通過節點指針操作,無需關心具體數據類型。
  • 符合 STL 容器的設計規范:STL 中所有容器都需要將 "元素存儲" 和 "容器管理" 分離,這樣才能統一迭代器接口。
  • list_node可以被視為一個通用的 "雙向節點模板",如果未來需要實現其他基于雙向節點的結構(如循環鏈表、隊列等),可以復用list_node的設計。
  • 當需要擴展鏈表功能時,只需修改list類的管理邏輯,無需改動list_node的結構。

2. list迭代器

2.1 三個可變參數的原因

我們在這里之所以要設置三個,是因為在list的迭代器里面需要不同的類型。同時一個可變參數在一個類里面只會推導一次,所以我們在這里是需要是三個。

  • T:鏈表中存儲的元素類型(如?intstring?等)。
  • Ref:迭代器解引用后返回的引用類型(普通迭代器用?T&,常量迭代器用?const T&)。
  • Ptr:迭代器通過?->?運算符返回的指針類型(普通迭代器用?T*,常量迭代器用?const T*)。
template<class T,class Ref,class Ptr>
struct _list_iterator{typedef list_node<T> Node;typedef _list_iterator<T, Ref, Ptr> self;Node* _node;};

2.2 構造函數

我們在這里又會有構造函數,是因為我們在list中實際上寫了三個類,一個list_iterator,一個list_node和一個list,這三者構成了完整的list。

這個就是在給list的迭代器進行初始化。因為是通過節點去訪問所以怎么寫。

_list_iterator(Node* node):_node(node)
{}

2.3?operator*()

返回對元素的引用Ref),模擬指針的解引用操作(如?*p?獲取指針指向的對象)。所以在這里要使用Ref。

Ref operator*()
{return _node->_val;
}

2.4?operator->()?

這邊的Ptr更多是為了結構體這種設計的,簡單來說這樣設計就是為了先進入結構體然后再訪問其內部成員。

那為什么要加&呢?這是因為operator要返回一個指針,然后我們通過這個指針來訪問結構體的內部成員。

Ptr operator->()
{return &_node->_val;
}

2.5 前置++

因為是前置的,所以是先++再return。

self?是迭代器類型本身(_list_iterator<T, Ref, Ptr>),它是一個 “指向元素的迭代器”,負責管理節點指針、提供遍歷能力。

self& operator++()
{_node = _node->_next;return *this;
}

2.6 后置++

這邊()里面的int是特殊處理,是為了和前置++構成函數重載。

又因為是后置++,所以我們讓迭代器向后走并返回走之前的值。

self operator++(int)
{self tmp(*this);_node = _node->next;return tmp;
}

2.7 前置--

因為是前置--,所以先返回上一個節點在return。

self& operator--()
{_node = _node->_prev;return *this;
}

2.8 后置--

因為是后置--,所以先保存節點在--。

int是為了和前置--構成函數重載。

self operator--(int)
{self tmp(*this);_node = _node->_prev;return tmp;
}

2.9 operator!=

這個加const是防止修改指向和被指向的內容。

因為是bool類型的,所以直接比較兩個指針的地址值是否一樣即可。

bool operator!=(const self& it) const
{return _node != it._node;
}

2.10 operator==

這個加const是防止修改指向和被指向的內容。

因為是bool類型的,所以直接比較兩個指針的地址值是否一樣即可。

bool operator==(const self& it) const
{return _node == it._node;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/919830.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/919830.shtml
英文地址,請注明出處:http://en.pswp.cn/news/919830.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

新能源汽車熱管理仿真:蒙特卡洛助力神經網絡訓練

研究背景在新能源汽車的熱管理仿真研究中&#xff0c;神經網絡訓練技術常被應用于系統降階建模。通過這一方法&#xff0c;可以構建出高效準確的代理模型&#xff0c;進而用于控制策略的優化、系統性能的預測與評估&#xff0c;以及實時仿真等任務&#xff0c;有效提升開發效率…

第十九講:C++11第一部分

目錄 1、C11簡介 2、列表初始化 2.1、{}初始化 2.2、initializer_list 2.2.1、成員函數 2.2.2、應用 3、變量類型推導 3.1、auto 3.2、decltype 3.3、nullptr 4、范圍for 5、智能指針 6、STL的一些變化 7、右值引用和移動語義 7.1、右值引用 7.2、右值與左值引…

書寫本體論視域下的文字學理論重構

在符號學與哲學的交叉領域&#xff0c;文字學&#xff08;Grammatologie&#xff09;作為一門顛覆性學科始終處于理論風暴的中心。自德里達1967年發表《論文字學》以來&#xff0c;傳統語言學中"語音中心主義"的霸權地位遭遇根本性動搖&#xff0c;文字不再被視為語言…

為什么要做架構設計?架構設計包含哪些內容?

大家好,我是IT孟德,You can call me Aman(阿瞞,阿彌陀佛的ē,Not阿門的ā),一個喜歡所有對象(熱愛技術)的男人。我正在創作架構專欄,秉承ITer開源精神分享給志同道合(愛江山愛技術更愛美人)的朋友。專欄更新不求速度但求質量(曹大詩人傳世作品必屬精品,請腦補一下《…

Vue2封裝Axios

一、介紹Axios 是一個基于 promise 的 HTTP 庫&#xff0c;簡單的講就是可以發送get、post等請求。二、安裝npm install axios --save二、axios不同請求方式axios(config)這是 Axios 的核心方法&#xff0c;用于發送自定義配置的 HTTP 請求。通過傳入一個包含請求配置的對象&am…

DataAnalytics之Tool:Metabase的簡介、安裝和使用方法、案例應用之詳細攻略

DataAnalytics之Tool&#xff1a;Metabase的簡介、安裝和使用方法、案例應用之詳細攻略 目錄 Metabase的簡介 1、特點 Metabase的安裝和使用方法 1、安裝 快速設置&#xff1a;開發環境 前端快速設置 后端快速設置 2、使用方法 Metabase的案例應用 Metabase的簡介 Met…

frp v0.64.0 更新:開源內網穿透工具,最簡潔教程

frp是一款跨平臺的內網穿透工具&#xff0c;支持 Windows、macOS 與 Linux&#xff0c;它需要你有一臺擁有固定公網 IP 的電腦&#xff0c;VPS 最好&#xff0c;然后就能愉快的進行內網穿透了。還支持 https&#xff0c;甚至可以用它進行小程序開發。Appinn v0.64.0 新增token…

【數據結構】B+ 樹——高度近似于菌絲網絡——詳細解說與其 C 代碼實現

文章目錄B 樹的定義B 樹組織數據的方法往 B 樹中插入鍵值對數據從 B 樹中刪除鍵值對把 B 樹看作是 “真菌網絡”——我理解并記憶 B 樹的方法B 樹的 C 代碼實現初始化節點、B 樹B 樹節點內的二分查找B 樹的數據插入操作B 樹的刪除數據操作范圍查詢與全局遍歷銷毀 B 樹測試代碼&…

01、數據結構與算法--順序表

正式進入數據結構的學習&#xff0c;先從預備知識學起&#xff0c;戒焦戒躁戒焦戒躁...一、泛型的引入1、為什么需要泛型&#xff1f;先來看一個題目&#xff1a;實現一個類&#xff0c;類中包含一個數組成員&#xff0c;使得數組中可以存放任何類型的數據&#xff0c;也可以根…

8.23打卡 DAY 50 預訓練模型+CBAM模塊

DAY 50: 預訓練模型與 CBAM 模塊的融合與微調 今天&#xff0c;我們將把之前學到的知識融會貫通&#xff0c;探討如何將 CBAM 這樣的注意力模塊應用到強大的預訓練模型&#xff08;如 ResNet&#xff09;中&#xff0c;并學習如何高效地對這些模型進行微調&#xff0c;以適應我…

北極圈邊緣生態研究:從數據采集到分析的全流程解析

原文鏈接&#xff1a;https://onlinelibrary.wiley.com/doi/10.1111/1744-7917.70142?afR北極圈邊緣生態研究&#xff1a;從數據采集到分析的全流程解析簡介本教程基于一項在俄羅斯摩爾曼斯克州基洛夫斯克市開展的長期生態學研究&#xff0c;系統講解如何對高緯度地區特定昆蟲…

Excel處理控件Aspose.Cells教程:使用Python將 Excel 轉換為 NumPy

使用 Python 處理 Excel 數據非常常見。這通常涉及將數據從 Excel 轉換為可高效操作的形式。將 Excel 數據轉換為可分析的格式可能非常棘手。在本篇教程中&#xff0c;您將學習借助強大Excel處理控件Aspose.Cells for Python&#xff0c;如何僅用幾行代碼將 Excel 轉換為 NumPy…

python 字典有序性的實現和OrderedDict

文章目錄 一、Python 3.7+ 字典有序性的驗證 二、如何在字典頭部插入鍵值對 方法 1:創建新字典(推薦) 方法 2:使用 `collections.OrderedDict`(適合頻繁頭部插入場景) 方法 3:轉換為列表操作(不推薦,效率低) 底層核心結構:雙數組哈希表 有序性的實現原理 與舊版本(…

JVM 調優全流程案例:從頻繁 Full GC 到百萬 QPS 的實戰蛻變

&#x1f525; JVM 調優全流程案例&#xff1a;從頻繁 Full GC 到百萬 QPS 的實戰蛻變 文章目錄&#x1f525; JVM 調優全流程案例&#xff1a;從頻繁 Full GC 到百萬 QPS 的實戰蛻變&#x1f9e9; 一、調優本質&#xff1a;性能瓶頸的破局之道&#x1f4a1; 為什么JVM調優如此…

基于TimeMixer現有腳本擴展的思路分析

文章目錄1. 加入數據集到data_loader.py和data_factory.py2. 參照exp_classification.py寫自定義分類任務腳本&#xff08;如exp_ADReSS.py&#xff09;3. 接一個MLP分類頭4. 嵌入指標計算、繪圖、保存訓練歷史的函數5. 開始訓練總結**一、可行性分析****二、具體實現步驟****1…

技術演進中的開發沉思-75 Linux系列:中斷和與windows中斷的區分

作為一名從 2000 年走過來的老程序員&#xff0c;看著 IT 技術從桌面開發迭代到微服務時代&#xff0c;始終覺得好技術就像老故事 —— 得有骨架&#xff08;知識點&#xff09;&#xff0c;更得有血肉&#xff08;場景與感悟&#xff09;。我想正是我的經歷也促成了我想寫這個…

【8位數取中間4位數】2022-10-23

緣由請輸入一個8位的十進制整數&#xff0c;編寫程序取出該整數的中間4位數&#xff0c;分別輸出取出的這4位數以及該4位數加上1024的得數。 輸入&#xff1a;一個整數。 輸出&#xff1a;兩個整數&#xff0c;用空格分隔-編程語言-CSDN問答 int n 0;std::cin >> n;std:…

mac電腦使用(windows轉Mac用戶)

首先&#xff0c;我們學習mac的鍵盤復制 command c 粘貼 command v 剪切 command xlinux命令行 退出中止 control c 退出后臺 control d中英文切換大小寫&#xff0c;按住左邊向上的箭頭 字母鼠標操作 滾輪&#xff1a;2個指頭一起按到觸摸板&#xff0c;上滑&#xff0c;…

項目中優惠券計算邏輯全解析(處理高并發)

其實這個部分的代碼已經完成一陣子了&#xff0c;但是想了一下決定還是整理一下這部分的代碼&#xff0c;因為最開始做的時候業務邏輯還是感覺挺有難度的整體流程概述優惠方案計算主要在DiscountServiceImpl類的findDiscountSolution方法中實現。整個計算過程可以分為以下五個步…

支持電腦課程、游戲、會議、網課、直播錄屏 多場景全能錄屏工具

白鯊錄屏大師&#xff1a;支持電腦課程、游戲、會議、網課、直播錄屏 多場景全能錄屏工具&#xff0c;輕松捕捉每一刻精彩 在數字化學習、娛樂與辦公場景中&#xff0c;高質量的錄屏需求日益增長。無論是課程內容的留存、游戲高光的記錄&#xff0c;還是會議要點的復盤、網課知…