C++初階——簡單實現vector

目錄

1、前言

2、Vector.h

3、Test.cpp


1、前言

簡單實現std::vector類模板。

相較于前面的string,vector要注意

深拷貝,因為vector的元素可能是類類型,類類型元素可以通過賦值重載自己實現深拷貝

迭代器失效,其實無非是兩種(現在認為):

1. 迭代器更新了,但是認為用的是之前的迭代器,可以先保存值。

2. 迭代器沒有更新,但是認為是用更新后的迭代器,那就更新迭代器。

2、Vector.h

#pragma once#include <iostream>
#include <vector>
#include <assert.h>using namespace std;namespace Lzc
{template <class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;vector() // 有了拷貝構造,就不會生成默認構造,但是需要默認構造{}vector(size_t n, const T& val = T())// int有默認構造int(),為了兼容模板{reserve(n);for (size_t i = 0; i < n; i++){push_back(val);}}template <class InputIterator> // 使用別的容器的迭代器初始化vector(InputIterator first, InputIterator last){// reserve(last - first);// last - first 有迭代器不支持減while (first != last){push_back(*first);++first;}}vector(const vector<T>& v){reserve(v.size());for (int i = 0; i < v.size(); i++){push_back(v[i]);}}void swap(vector<T>& tmp){std::swap(_start, tmp._start);std::swap(_finish, tmp._finish);std::swap(_end_of_storage, tmp._end_of_storage);}vector& operator=(const vector<T>& v){vector tmp(v);swap(tmp);return *this;}~vector(){if (_start){delete[] _start;_start = _finish = _end_of_storage = nullptr;}}iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}size_t size() const{return _finish - _start;}size_t capacity() const{return _end_of_storage - _start;}void clear(){_finish = _start;}bool empty() 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()); // resize一般用于擴容+初始化void reserve(size_t n);void push_back(const T& val){if (size() == capacity())reserve(capacity() == 0 ? 4 : 2 * capacity());*_finish = val;++_finish;}void pop_back(){assert(size() > 0);--_finish;}iterator insert(iterator pos, const T& val);iterator erase(iterator pos);private:iterator _start = nullptr;iterator _finish = nullptr;iterator _end_of_storage = nullptr;};template<class T>void vector<T>::resize(size_t n, const T& val) // resize一般用于擴容+初始化{if (n < size()){_finish = _start + n;}else{reserve(n);while (_finish < _start + n){*_finish = val;++_finish;}}}template<class T>void vector<T>::reserve(size_t n){if (n > capacity()){size_t old_size = size();T* tmp = new T[n];for (size_t i = 0; i < old_size; i++){tmp[i] = _start[i]; // 若為類類型,會賦值重載,先釋放,再深拷貝}delete[] _start;_start = tmp;_finish = tmp + old_size; // 不能調用size(),因為_start已更新,所以先保存size()_end_of_storage = tmp + n;}}// vector<T>::iterator編譯器認為是類中的靜態變量,typename告訴編譯器是類型template<class T>typename vector<T>::iterator vector<T>::insert(iterator pos, const T& val){assert(pos <= _finish);assert(pos >= _start);if (size() == capacity()){size_t old_pos = pos - _start; // 擴容后pos沒有指向新空間reserve(capacity() == 0 ? 4 : 2 * capacity());pos = _start + old_pos;}iterator it = _finish;while (it != pos){*it = *(it - 1); // 若為類類型,會賦值重載,先釋放,再深拷貝--it;}*pos = val;++_finish;return pos;}template<class T>typename vector<T>::iterator vector<T>::erase(iterator pos){assert(pos >= _start);assert(pos < _finish);iterator it = pos + 1;while (it != end()){*(it - 1) = *it; // 若為類類型,會賦值重載,先釋放,再深拷貝++it;}--_finish;return pos;}template<class Container> // 什么容器都能打印void print_Container(const Container& v){for (const auto& e : v){cout << e << " ";}cout << endl;}
}

3、Test.cpp

#include "Vector.h"
#include <list>
#include <string>namespace Lzc
{void test_vector1(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);for (size_t i = 0; i < v.size(); i++){cout << v[i] << " ";}cout << endl;//vector<int>::iterator it = v.begin();auto it = v.begin();while (it != v.end()){cout << *it << " ";++it;}cout << endl;for (auto e : v){cout << e << " ";}cout << endl;vector<double> vd;vd.push_back(1.1);vd.push_back(1.2);vd.push_back(1.3);vd.push_back(1.4);vd.push_back(1.5);print_Container(vd);}void test_vector2(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);print_Container(v);// 若iterator insert(iterator& pos, const T& val)// 下面的臨時變量(具有常性),不能傳引用/*v.insert(v.begin() + 2, 30);print_vector(v);*/int x;cin >> x;auto p = find(v.begin(), v.end(), x);if (p != v.end()){// insert以后p就是失效,不要直接訪問,要訪問就要更新這個失效的迭代器的值/*v.insert(p, 20);(*p) *= 10;*/p = v.insert(p, 40);(*(p + 1)) *= 10;}print_Container(v);}void test_vector3(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);//v.push_back(5);print_Container(v);// 刪除所有的偶數auto it = v.begin();while (it != v.end()){if (*it % 2 == 0){it = v.erase(it); // 刪除了,相當于++了}else{++it;}}print_Container(v);}void test_vector4(){int i = int(); // int有默認構造int(),為了兼容模板int j = int(1);int k(2);vector<int> v;v.resize(10, 1);v.reserve(20);print_Container(v);cout << v.size() << endl;cout << v.capacity() << endl;v.resize(15, 2);print_Container(v);v.resize(25, 3);print_Container(v);v.resize(5);print_Container(v);}void test_vector5(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);print_Container(v1);vector<int> v2 = v1;print_Container(v2);vector<int> v3;v3.push_back(10);v3.push_back(20);v3.push_back(30);v1 = v3;print_Container(v1);print_Container(v3);}void test_vector6(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(4);v1.push_back(4);vector<int> v2(v1.begin(), v1.begin() + 3);print_Container(v1);print_Container(v2); // 1 2 3list<int> lt;lt.push_back(10);lt.push_back(10);lt.push_back(10);lt.push_back(10);vector<int> v3(lt.begin(), lt.end()); print_Container(lt);print_Container(v3);// 10 10 10 10vector<string> v4(10, "1111111");print_Container(v4);vector<int> v5(10);print_Container(v5);vector<int> v6(10u, 1); // 指定構造函數,不然編譯器會使用模板函數。print_Container(v6);    // vector(size_t n, const T& val = T())//vector<int> v7(10, 1); // 編譯器會使用模板函數,報錯//print_Container(v7); // 可以再重載一個vector(int n, const T& val = T())}void test_vector7() // 擴容后需深拷貝{vector<string> v;v.push_back("11111111111111111111");v.push_back("11111111111111111111");v.push_back("11111111111111111111");v.push_back("11111111111111111111");print_Container(v);v.push_back("11111111111111111111");print_Container(v);}
}int main()
{Lzc::test_vector7();return 0;
}

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

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

相關文章

全志A133 android10 適配SLM770A 4G模塊

一&#xff0c;模塊基本信息 1.官方介紹 SLM770A是美格智能最新推出的一款LTE Cat.4無線通訊模組&#xff0c;最大支持下行速率150Mbps及上行速率50Mbps。同時向下兼容現有的3G和2G網絡&#xff0c;以確保即使在偏遠地區也可以進行網絡通信。 SLM770A模組支持分集接收和MIMO技…

微信小程序:多菜單欄設計效果

一、實現效果 二、代碼 wxml 編輯前端界面,步驟 菜單邏輯: 逐步取出數組中的項,首先取出頂部菜單項,然后選中后取出選中的底部數據(左側菜單+右側內容),然后點擊左側菜單取出選中的左側菜單對應的右側內容 ①這里我的數據是全部封裝到一個數組對象的,首先我的循環…

C++基礎知識學習記錄—string類

string實際上是C內置的一個類&#xff0c;內部對char *進行了封裝&#xff0c;不用擔心數組越界問題&#xff0c;string類中&#xff0c;除了上課講解的函數外&#xff0c;還有很多函數可以使用&#xff0c;可以自行查閱文檔。 構造函數原型&#xff1a; string(); //創建一個…

Ollama+DeepSeek+Open-WebUi

環境準備 Docker Ollama Open-WebUi Ollama 下載地址&#xff1a;Ollama docker安裝ollama docker run -d \ -v /data/ollama/data:/root/.ollama \ -p 11434:11434 \ --name ollama ollama/ollama 下載模型 Ollama模型倉庫 # 示例&#xff1a;安裝deepseek-r1:7b doc…

設計模式--訪問者模式【行為型模式】

設計模式的分類 我們都知道有 23 種設計模式&#xff0c;這 23 種設計模式可分為如下三類&#xff1a; 創建型模式&#xff08;5 種&#xff09;&#xff1a;單例模式、工廠方法模式、抽象工廠模式、建造者模式、原型模式。結構型模式&#xff08;7 種&#xff09;&#xff1…

前端循環全解析:JS/ES/TS 循環寫法與實戰示例

循環是編程中控制流程的核心工具。本文將詳細介紹 JavaScript、ES6 及 TypeScript 中各種循環的寫法、特性&#xff0c;并通過實際示例幫助你掌握它們的正確使用姿勢。 目錄 傳統三劍客 for 循環 while 循環 do...while 循環 ES6 新特性 forEach for...of for...in 數組…

數據中心儲能蓄電池狀態監測管理系統 組成架構介紹

安科瑞劉鴻鵬 摘要 隨著數據中心對供電可靠性要求的提高&#xff0c;蓄電池儲能系統成為關鍵的后備電源。本文探討了蓄電池監測系統在數據中心儲能系統中的重要性&#xff0c;分析了ABAT系列蓄電池在線監測系統的功能、技術特點及其應用優勢。通過蓄電池監測系統的實施&#…

Mac端homebrew安裝配置

拷打了一下午o3-mini-high&#xff0c;不如這位博主的超強帖子&#xff0c;10分鐘結束戰斗 跟隨該文章即可&#xff0c;2025/2/19親測可行 mac 安裝HomeBrew(100%成功)_mac安裝homebrew-CSDN博客文章瀏覽閱讀10w次&#xff0c;點贊258次&#xff0c;收藏837次。一直覺得自己寫…

機器學習實戰(8):降維技術——主成分分析(PCA)

第8集&#xff1a;降維技術——主成分分析&#xff08;PCA&#xff09; 在機器學習中&#xff0c;降維&#xff08;Dimensionality Reduction&#xff09; 是一種重要的數據處理技術&#xff0c;用于減少特征維度、去除噪聲并提高模型效率。主成分分析&#xff08;Principal C…

windows環境下用docker搭建php開發環境dnmp

安裝WSL WSL即Linux子系統&#xff0c;比虛擬機占用資源少&#xff0c;安裝的前提是系統必須是win10以上。 WSL的安裝比較簡單&#xff0c;網上有很多教程&#xff0c;例如&#xff1a;WSL簡介與安裝流程&#xff08;Windows 下的 Linux 子系統&#xff09;_wsl安裝-CSDN博客&…

Python網絡爬蟲技術詳解文檔

Python網絡爬蟲技術詳解文檔 目錄 網絡爬蟲概述爬蟲核心技術解析常用Python爬蟲庫實戰案例演示反爬蟲機制與應對策略爬蟲法律與道德規范高級爬蟲技術資源推薦與學習路徑1. 網絡爬蟲概述 1.1 什么是網絡爬蟲 網絡爬蟲(Web Crawler)是一種按特定規則自動抓取互聯網信息的程序…

位運算,雙指針,二分,排序算法

文章目錄 位運算二進制中1的個數題解代碼我們需要0題解代碼 排序模版排序1題解代碼模版排序2題解代碼模版排序3題解代碼 雙指針最長連續不重復子序列題解代碼 二分查找題解代碼 位運算 1. bitset< 16 >將十進制數轉為16位的二進制數 int x 25; cout << bitset<…

一周學會Flask3 Python Web開發-redirect重定向

鋒哥原創的Flask3 Python Web開發 Flask3視頻教程&#xff1a; 2025版 Flask3 Python web開發 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 前面我們學過渲染到模板頁面&#xff0c;這個其實是一種內部的轉發&#xff0c;瀏覽器地址欄地址沒有變化。如果我們想重定向…

圖片粘貼上傳實現

圖片上傳 html demo 直接粘貼本地運行查看效果即可&#xff0c;有看不懂的直接喂給 deepseek 會解釋的很清晰 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"…

RedisTemplate存儲含有特殊字符解決

ERROR信息: 案發時間: 2025-02-18 01:01 案發現場: UserServiceImpl.java 嫌疑人: stringRedisTemplate.opsForValue().set(SystemConstants.LOGIN_CODE_PREFIX phone, code, Duration.ofMinutes(3L)); // 3分鐘過期作案動機: stringRedisTemplate繼承了Redistemplate 使用的…

Python正則表達式學習

Python正則表達式全攻略 一、正則表達式基礎 1. 什么是正則表達式&#xff1f; 用于描述字符串匹配規則的表達式廣泛應用于文本處理、表單驗證、數據清洗等領域 2. Python中的re模塊 import re3. 基礎語法 字符說明示例.匹配任意字符(除換行)a.c → abc\d數字 [0-9]\d\d …

20250218 隨筆 垂直分庫分表(Vertical Sharding) 和 水平分庫分表(Horizontal Sharding)

垂直分庫分表&#xff08;Vertical Sharding&#xff09; 和 水平分庫分表&#xff08;Horizontal Sharding&#xff09; 是數據庫拆分的兩種策略。它們在大規模數據庫優化、分布式架構設計中至關重要&#xff0c;主要用于 降低單庫壓力、提高查詢效率、支持高并發。 1. 垂直分…

notepad++右鍵菜單不見了

卸載時沒點擊完成&#xff0c;又重新安裝了一個&#xff0c;最終導致了一些bug&#xff0c;導致右鍵沒有notepad菜單。 解決方式&#xff1a; 新建一個register.reg文件&#xff0c;加入以下代碼&#xff0c;然后雙擊執行即可 代碼說明&#xff1a;Open with Notepad 是右…

重定向與文件緩沖機制

目錄 一、重定向的原理與實踐 1. 輸出重定向&#xff1a;讓數據流向新目的地 2. 追加重定向&#xff1a;在文件末尾追加數據 3. 輸入重定向&#xff1a;從指定文件讀取數據 4. 標準輸出流與標準錯誤流的區別 5. 使用 dup2 實現重定向 二、FILE 結構體的奧秘 1. FILE 中的…

DeepSeek 沖擊(含本地化部署實踐)

DeepSeek無疑是春節檔最火爆的話題&#xff0c;上線不足一月&#xff0c;其全球累計下載量已達4000萬&#xff0c;反超ChatGPT成為全球增長最快的AI應用&#xff0c;并且完全開源。那么究竟DeepSeek有什么魔力&#xff0c;能夠讓大家趨之若鶩&#xff0c;他又將怎樣改變世界AI格…