網站首頁 編程語言 正文
向量
向量是序列容器,表示可以更改大小的數組。
就像數組一樣,向量對其元素使用連續的存儲位置,這意味著也可以使用指向其元素的常規指針上的偏移量來訪問其元素,并且與數組一樣高效。但與數組不同的是,它們的大小可以動態變化,它們的存儲由容器自動處理。
在內部,向量使用動態分配的數組來存儲其元素。可能需要重新分配此數組,以便在插入新元素時增加大小,這意味著分配新數組并將所有元素移動到該數組。就處理時間而言,這是一項相對昂貴的任務,因此,每次將元素添加到容器時,向量都不會重新分配。
相反,向量容器可以分配一些額外的存儲以適應可能的增長,因此容器的實際容量可能大于嚴格需要的存儲來包含其元素(即其大小)。庫可以實現不同的增長策略,以平衡內存使用和重新分配,但無論如何,重新分配應僅以對數增長的大小間隔發生,以便可以在向量末尾插入單個元素,并提供攤銷的恒定時間復雜性。
因此,與數組相比,向量消耗更多的內存,以換取管理存儲和以有效方式動態增長的能力。
與其他動態序列容器(deques、list 和 forward_lists)相比,向量非常有效地訪問其元素(就像數組一樣),并且相對有效地從其末尾添加或刪除元素。對于涉及在末尾以外的位置插入或刪除元素的操作,它們的性能比其他元素差,并且迭代器和引用的一致性低于 lists 和 forward_lists。
成員函數
(構造函數) 構造 vector(公開成員函數) (析構函數) 析構 vector(公開成員函數) operator= 賦值給容器(公開成員函數) assign 將值賦給容器(公開成員函數) get_allocator 返回相關的分配器(公開成員函數) 元素訪問 at 訪問指定的元素,同時進行越界檢查(公開成員函數) operator[] 訪問指定的元素(公開成員函數) front 訪問第一個元素(公開成員函數) back 訪問最后一個元素(公開成員函數) data 直接訪問底層數組(公開成員函數) 迭代器 begin,cbegin(C++11) 返回指向起始的迭代器(公開成員函數) end,cend(C++11) 返回指向末尾的迭代器(公開成員函數) rbegin,crbegin(C++11) 返回指向起始的逆向迭代器(公開成員函數) rend,crend(C++11) 返回指向末尾的逆向迭代器(公開成員函數) 容量 empty 檢查容器是否為空(公開成員函數) size 返回容納的元素數(公開成員函數) max_size 返回可容納的最大元素數(公開成員函數) reserve 預留存儲空間(公開成員函數) capacity 返回當前存儲空間能夠容納的元素數(公開成員函數) shrink_to_fit(C++11) 通過釋放未使用的內存減少內存的使用(公開成員函數) 修改器 clear 清除內容(公開成員函數) insert 插入元素(公開成員函數) emplace(C++11) 原位構造元素(公開成員函數) erase 擦除元素(公開成員函數) push_back 將元素添加到容器末尾(公開成員函數) emplace_back(C++11) 在容器末尾就地構造元素(公開成員函數) pop_back 移除末元素(公開成員函數) resize 改變容器中可存儲元素的個數(公開成員函數) swap 交換內容(公開成員函數) 非成員函數 按照字典順序比較 vector 中的值(函數模板) operator== operator!=(C++20 中移除) operator<(C++20 中移除) operator<=(C++20 中移除) operator>(C++20 中移除) operator>=(C++20 中移除) operator<=>(C++20) std::swap(std::vector) 特化 std::swap 算法(函數模板) erase(std::vector),erase_if(std::vector) (C++20) 擦除所有滿足特定判別標準的元素(函數模板
cpp
templateclass Vector { public: Vector() noexcept = default; explicit Vector(size_t n) : cap_{n}, ptr_{alloc(cap_)} { for (; len_ < n; ++len_) { construct(ptr_ + len_); //調用T的默認構造 } } Vector(size_t n, const T &x) : cap_{n}, ptr_{alloc(cap_)} { for (; len_ < n; ++len_) { construct(ptr_ + len_, x); //調用T的拷貝構造 } } Vector(const Vector &x) : cap_{x.size()}, ptr_{alloc(cap_)} //拷貝構造 { for (; len_ < x.size(); ++len_) { construct(ptr_ + len_, x[len_]); } } Vector(Vector &&x) noexcept //移動構造 { cap_ = std::__exchange(x.cap_, 0); len_ = std::__exchange(x.len_, 0); ptr_ = std::__exchange(x.ptr_, nullptr); } Vector(std::initializer_list li) : cap_{li.size()}, ptr_{alloc(cap_)} //初始化列表 { for (auto &x : li) { construct(ptr_ + len_, x); ++len_; } } ~Vector() noexcept { clear(); dealloc(ptr_); } void swap(Vector &x) noexcept { using std::swap; // ADL swap(cap_, x.cap_); swap(len_, x.len_); swap(ptr_, x.ptr_); } void clear() noexcept { for (; len_ > 0; --len_) { destroy(ptr_ + len_ - 1); } } Vector &operator=(const T &x) //拷貝賦值 { if (this != &x) { Vector{x}.swap(*this); } return *this; } Vector &operator=(T &&x) noexcept //移動賦值 { if (this != &x) { Vector{std::move(x)}.swap(*this); } return *this; } Vector &operator=(std::initializer_list li) //初始化列表賦值 { Vector{li}.swap(*this); return *this; } void push_back(const T &x) //拷貝 { emplace_back(x); } void push_back(T &&x) //移動 { emplace_back(x); } template void emplace_back(Args &&...args) //直接傳遞構造函數 { if (len_ == cap_) { size_t new_cap = cap_ ? cap_ * 2 : 1; //等0返回1 T *new_ptr = alloc(new_cap); for (size_t new_len; new_len < len_; ++new_len) { construct(new_ptr + new_len, std::move_if_noexcept(ptr_[new_len])); } cap_ = new_cap; ptr_ = new_ptr; } construct(ptr_ + len_, std::forward(args)...); ++len_; } void pop_back() noexcept { if (len_ < cap_ / 2) { size_t new_cap = cap_ / 2; T *new_ptr = alloc(new_cap); for (size_t new_len = 0; new_len < len_; ++new_len) { construct(new_ptr + new_len, std::move_if_noexcept(ptr_[new_len])); } cap_ = new_cap; ptr_ = new_ptr; } destroy(ptr_ + len_ - 1); --len_; } size_t size() const noexcept { return len_; } size_t capacity() const noexcept { return cap_; } bool empty() const noexcept { return len_ == 0; } T &operator[](size_t i) { return ptr_[i]; } const T &operator[](size_t i) const { return ptr_[i]; } T *begin() noexcept { return ptr_; } T *end() noexcept { return ptr_ + len_; } const T *begin() const noexcept { return ptr_; } const T *end() const noexcept { return ptr_ + len_; } private: T *alloc(size_t n) //分配n個大小內存 { return static_cast (::operator new(sizeof(T) * n)); } void dealloc(T *p) noexcept //釋放內存 { ::operator delete(p); } template void construct(T *p, Args &&...args) //在這塊內存上構造T類型對象 { ::new (p) T(std::forward (args)...); } void destroy(T *p) noexcept { p->~T(); } private: size_t cap_{0}; //容量 size_t len_{0}; //元素個數 T *ptr_{nullptr}; };
總結
原文鏈接:https://blog.csdn.net/Cdreamfly/article/details/123315354
相關推薦
- 2022-10-18 linux下shell腳本備份文件的方法實現_linux shell
- 2022-09-17 詳解redis集群的三種方式_Redis
- 2022-08-11 boost.asio框架系列之調度器io_service_C 語言
- 2022-07-12 Docker-swarm快速搭建redis集群的方法步驟_docker
- 2023-01-26 Redis中的配置文件,數據持久化,事務_Redis
- 2022-05-28 Python讀取文件的四種方式的實例詳解_python
- 2022-10-31 Python3邏輯運算符與成員運算符_python
- 2022-07-06 C#winform中數據庫綁定DataGrid的實現_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支