C++之vector類的代碼及其邏輯詳解 (下)

1.?insert()

這個就是在指定位置插入一個元素,首先計算要插入的這個位置和開頭之間的距離,接著判斷那個_finish?有沒有碰到_endofstorage 或者_endofstorage 是不是為0,如果滿足條件,那就進行擴容,然后接著重新計算距離,因為我們經過擴容了,所以可能插入的位置會不準,所以要重新計算,接著我們算一個end,這個end就是最后一個元素的位置,然后通過挪動的方式留出pos的空間,接著插入對應元素再++_finish 。

void insert(iterator pos, const T& x)
{assert(pos >= _start && pos <= _finish);size_t len = pos - _start;if (_finish == _endofstorage && _endofstorage != 0){reserve(capacity() * 2);}else{reserve(4);}pos = _start + len;iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;--end;}*pos = x;++_finish;}

2. reserve()

這個函數就是改變vector的capacity,同時并不像resize一樣會添加或者減少元素。

首先保存當前元素數量 sz,然后動態分配大小為 n 的新內存 tmp。若原內存_start 非空,則通過循環調用元素的賦值運算符將原數據逐個復制到新內存中(而非直接使用 memcpy,避免淺拷貝問題),隨后釋放原內存。最后更新_start 指向新內存,_finish 指向原元素末尾的下一個位置,_endofstorage 指向新容量的末尾。若 n 不大于當前容量,則不執行任何操作。

簡單來說就是新開一個擴容后數組然后把舊的賦值給他,接著直接把原來的vector的三個指針直接指向新的,從而完成替換實現reserve。

void reserve(size_t n)
{if (n > capacity()){size_t sz = size();T* tmp = new T[n];if (_start){//memcpy(tmp, _start, sizeof(T) * sz);for (int i = 0; i < sz; i++) {tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + sz;_endofstorage = _start + n;}
}

3.? resize()

這個函數就是改變vector的大小,如果比原來的size小,那就改變finish的位置。

如果比原來的size大,那就吧finish向后移動,并在每一個添加的位置賦值為val。

PS:這個val之所以要設計成const T& val=T(),是因為我們并不知道這個vector里面是什么類型的,在加上這個resize在stl庫里面支持只給一個n,所以我們在這里就這么設計。意思是表用它的默認構造,我們在這里不用擔心int這種內置類型,因為C++支持像int a=int(1)這種語法了。

void resize(size_t n, const T& val=T())
{if (n < size()){_finish = _start + n;}else{reserve(n);while (_finish != _start + n){*(_finish) = val;++_finish;}}
}

4. swap()

這個的話就是交換兩個vetcor里面的內容。

原理上來說的話就是通過swap兩個vector里面的三個指針來實現。

void swap(vector<T>& v)
{std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);
}

5. capacity()

這個的話就是返回vector的capacity,因為_endofstorage和_start是指針而不是實際的大小,所以我們在這里要做減法。

size_t capacity() const
{return (_endofstorage - _start);
}

6. size()

這個的話就是返回vector的size,原因的話和上面一樣。

size_t size() const
{return (_finish - _start);
}

7. operator[]

這個的話是運算符重載的[],簡單來說就是可以通過下標的方式來對vector里面的內容進行訪問。

同時在這里提供了普通版本和const版本。

T& operator[](size_t pos)
{	assert(pos < size());return _start[pos];
}const T& operator[](size_t pos) const
{assert(pos < size());return _start[pos];
}

8. print()

這個就是打印,通過迭代器的方式來對vector里面的內容進行打印。

void print()
{for (auto e : *this){std::cout << e << ' ';}cout << endl;
}

?9. 總結

本文圍繞C++中的vector容器展開了全面解析,從基礎特性到具體接口操作進行了系統梳理。

首先,明確了vector的核心特性及空間結構,讓讀者對其底層存儲有了整體認知;接著,深入講解了vector類的關鍵成員與函數,包括私有成員的作用,以及構造函數(默認、拷貝、范圍構造)和析構函數在對象創建與銷毀時的機制;同時,詳細介紹了迭代器相關的begin、end接口,以及erase、pop_back、insert等元素增刪操作,reserve、resize、swap等空間與容器管理函數,還有capacity、size的獲取方式;此外,還涵蓋了重載的方括號運算符(用于便捷訪問元素)和print方法(用于元素輸出)。

通過這些內容,全面呈現了vector的使用邏輯與核心功能,幫助讀者從底層原理到實際操作,完整掌握vector容器的應用。

以下是vector的完整代碼:

#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
namespace struggle
{template<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}vector(size_t n, const T& val = T()){resize(n, val);}vector(int n, const T& val = T()){resize(n, val);}template<class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}vector(const vector<T>& v){_start = new T[v.capacity()];for (size_t i = 0; i < v.size(); i++){_start[i] = v._start[i];}_finish =_start+v.size();_endofstorage = _start + v.capacity();}void swap(vector<T>& v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);}vector<T>& operator=(vector<T> v){swap(v);return *this;}vector():_start(nullptr), _finish(nullptr), _endofstorage(nullptr){}~vector(){delete[] _start;_start = _finish = _endofstorage = 0;}void reserve(size_t n){if (n > capacity()){size_t sz = size();T* tmp = new T[n];if (_start){//memcpy(tmp, _start, sizeof(T) * sz);for (int i = 0; i < sz; i++) {tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + sz;_endofstorage = _start + n;}}void push_back(const T& x){if (_finish == _endofstorage && _endofstorage != 0){reserve(capacity() * 2);}else{reserve(4);}*_finish = x;++_finish;}size_t capacity() const{return (_endofstorage - _start);}size_t size() const{return (_finish - _start);}T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos) const{assert(pos < size());return _start[pos];}void resize(size_t n, const T& val=T()){if (n < size()){_finish = _start + n;}else{reserve(n);while (_finish != _start + n){*(_finish) = val;++_finish;}}}void erase(iterator pos){assert(pos >= _start && pos < _finish);iterator it = pos;while (it + 1 != _finish){*it = *(it + 1);++it;}--_finish;}void pop_back(){assert(_start != _finish);--_finish;}void insert(iterator pos, const T& x){assert(pos >= _start && pos <= _finish);size_t len = pos - _start;if (_finish == _endofstorage && _endofstorage != 0){reserve(capacity() * 2);}else{reserve(4);}pos = _start + len;iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;--end;}*pos = x;++_finish;}/*void print(const vector<int>& v){for(auto e:v){std::cout << e << ' ';}cout << endl;}*/void print(){for (auto e : *this){std::cout << e << ' ';}cout << endl;}private:iterator _start;iterator _finish;iterator _endofstorage;};
}

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

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

相關文章

【自動化測試】Python Selenium 自動化測試元素定位專業教程

1. 引言&#xff1a;元素定位在 Selenium 中的核心地位 元素定位是 Selenium 自動化測試的基礎&#xff0c;所有用戶交互操作&#xff08;如點擊、輸入、選擇&#xff09;都依賴于準確識別頁面元素。Selenium WebDriver 提供了多種定位策略&#xff0c;從簡單的 ID 定位到復雜…

通用代碼自用

多文件上傳public int save(Role role, RequestParam("nfile") MultipartFile nfile, HttpServletRequest request) {System.out.println(nfile.getOriginalFilename());String path request.getSession().getServletContext().getRealPath("/upload");Fi…

生成式AI如何顛覆我們的工作和生活

原問題&#xff1a; ?你覺得生成式AI未來會如何改變普通人的工作和生活&#xff1f;? 做過一個對比國外和國內工業化產品制造的簡單調研&#xff0c;類似一款定制化的臺燈或者語音音響&#xff0c;從零到原型實物&#xff0c; 美國至少需要20萬美刀&#xff0c;國內成本大概…

K8S、Docker安全漏洞靶場

1 介紹 一個脆弱基礎設施自動化構建框架,主要用于快速、自動化搭建從簡單到復雜的脆弱云原生靶機環境。 1.1 項目的緣起 在研究漏洞時,我們經常會發現“環境搭建”這一步驟本身就會占用大量的時間,與之相比,真正測試PoC、ExP的時間可能非常短。由于許多官方鏡像在國內的…

使用Nginx部署前后端分離項目

使用Nginx部署前后端分離項目&#xff1a;用戶中心系統實踐指南 部署前的關鍵準備 在正式部署前&#xff0c;務必確保前后端在生產環境能正常運行&#xff1a; 前端&#xff1a;測試所有API請求路徑和生產環境配置后端&#xff1a;驗證數據庫連接、環境變量和外部服務集成完整流…

當前就業形勢下,軟件測試工程師職業發展與自我提升的必要性

軟件測試行業正處于深刻變革期&#xff0c;2025年的市場已超越400億美元規模&#xff0c;預計2027年將增長7% 。在這個技術驅動、效率至上的時代&#xff0c;測試工程師若想保持競爭力&#xff0c;必須主動擁抱變革&#xff0c;系統性提升技能。通過深入分析行業現狀與人才需求…

java 之 繼承

一、繼承 1.1 、什么是繼承&#xff1f; 繼承就是把所有的類的公共部分&#xff08;相同的成員&#xff09;提取出來&#xff0c;放到一個類中繼承需要使用 extends 關鍵字 public class Animal{ public String name&#xff1b; } public class Dog extends Animal{}Dog 是 An…

強化應急通信生命線:遨游三防平板、衛星電話破局極端災害救援

暴雨傾盆&#xff0c;山洪咆哮&#xff0c;城市陷入內澇。今年進入汛期以來&#xff0c;我國廣東、福建、河南、陜西、京津冀等地相繼遭遇暴雨、洪澇、山洪等災害&#xff0c;道路損毀、基站斷網、電力中斷等次生問題為應急響應帶來嚴峻挑戰。如何保障極端場景下的通信暢通&…

【Linux系統】進程間通信:命名管道

1. 匿名管道的限制匿名管道存在以下核心限制&#xff1a;僅限親緣關系進程&#xff1a;只能用于父子進程等有血緣關系的進程間通信&#xff08;如通過 fork() 創建的子進程&#xff09;。單向通信&#xff1a;數據只能單向流動&#xff08;一端寫&#xff0c;另一端讀&#xff…

Python Day24 多線程編程:核心機制、同步方法與實踐案例

一、線程事件對象&#xff08;threading.Event&#xff09;threading.Event 用于實現線程間的通信&#xff0c;可讓一個線程通知其他線程終止任務&#xff0c;核心是通過 “事件觸發” 機制協調線程行為。核心方法&#xff1a;創建事件對象&#xff1a;event threading.Event(…

007 前端( JavaScript HTML DOM+Echarts)

一.html dom運用查找html元素的三種方式通過 id 找到 HTML 元素通過標簽名找到 HTML 元素通過類名找到 HTML 元素1.通過 id 找到 HTML 元素<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>msf的網頁</title> <…

實習文檔背誦

實習內容:1.定時任務與數據補全:基于 XXL-JOB 實現分布式定時任務調度&#xff0c;補全近半年歷史操作日志數據&#xff0c;有效解決因網絡異常導致的數據缺失問題。業務場景&#xff1b;集團的4a日志半年內沒有同步&#xff0c;這邊需要把日志數據同步到集團上首先先評估每天的…

分布式CAP定理

CAP 定理在一個分布式系統中&#xff0c;以下三個特性不可能同時完全滿足&#xff0c;最多只能滿足其中兩個&#xff1a;C&#xff08;Consistency&#xff0c;一致性&#xff09;&#xff1a;所有節點在同一時間看到的數據是完全一致的&#xff08;即更新操作成功并返回后&…

PHP-Casbin:現代化 PHP 應用的權限管理引擎

在當今復雜的Web應用中&#xff0c;精細化的權限管理是保障系統安全的關鍵環節。PHP-Casbin 作為Casbin生態的PHP實現&#xff0c;憑借其靈活的模型支持和強大的擴展能力&#xff0c;已成為PHP開發者實現訪問控制的首選工具。 超越傳統權限模型 PHP-Casbin 基于PERM&#xff…

FastDeploy2.0:環境變量的說明

一、執行# 設置日志目錄 export FD_LOG_DIR/workspace/models/log# 指定使用的 GPU 設備 export CUDA_VISIBLE_DEVICES0,1,2,3# 創建日志目錄&#xff08;如果不存在&#xff09; mkdir -p "$FD_LOG_DIR"# 定義日志文件路徑 LOG_FILE"$FD_LOG_DIR/fastdeploy_se…

C語言:指針(1-2)

5. 指針運算指針的基本運算有三種&#xff0c;分別是&#xff1a;指針-整數指針-指針指針的關系運算5.1 指針運算在上面&#xff0c;我們知道&#xff0c;數組在內存中是連續存放的&#xff0c;只要知道第一個元素的地址&#xff0c;順藤摸瓜就能找到后面的所有元素。那么&…

【多模態】DPO學習筆記

DPO學習筆記1 原理1.0 名詞1.1 preference model1.2 RLHF1.3 從RLHF到DPOA.解的最優形式B. DPO下參數估計C. DPO下梯度更新D. DPO訓練的穩定性2 源代碼2.1 數據集構成2.2 計算log prob2.3 DPO loss1 原理 1.0 名詞 preference model&#xff1a;對人類偏好進行建模&#xff0…

2025最新、UI媲美豆包、DeepSeek等AI大廠的AIGC系統 - IMYAI源碼部署教程

IMYAI 系統部署與使用手冊 一、系統演示 &#x1f539; 快速體驗 前端演示地址&#xff1a;https://super.imyaigc.com后臺演示地址&#xff1a;https://super.imyaigc.com/settings &#x1f539; 技術架構 前端&#xff1a;Vite Vue3 NaiveUI TailwindCSS Plyr后端&…

【關于Java的反射】

在 Java 編程中&#xff0c;反射&#xff08;Reflection&#xff09; 是一個非常強大的工具&#xff0c;它允許你在運行時動態地獲取類的信息、創建對象、調用方法和訪問字段。雖然反射功能強大&#xff0c;但它也有一些局限性和性能開銷&#xff0c;因此需要謹慎使用。一、什么…

Gitee推出“移動軟件工廠“解決方案 解決嵌入式與涉密場景研發困局

Gitee推出"移動軟件工廠"解決方案 破解嵌入式與涉密場景研發困局 隨著數字化轉型浪潮的推進&#xff0c;軟件開發正面臨著前所未有的復雜環境挑戰。特別是在嵌入式系統、FPGA開發以及涉密信息系統等特殊場景下&#xff0c;研發團隊往往需要在高安全要求與有限網絡環境…