網站首頁 編程語言 正文
一、基礎框架
template<class T>
class vector
{
public:
typedef T* iterator;
typedef const T* const_iterator;
private:
iterator _start;//指向第一個元素
iterator _finish;//指向最后一個元素的下一個位置
iterator _endofstoage;//容量
};
二、迭代器實現
const_iterator begin() const
{
return _str;
}
const_iterator end() const
{
return _str + _size;
}
iterator begin()
{
return _str;
}
iterator end()
{
return _str + _size;
}
三、size capacity resize reserve
size_t size() const
{
return _finish - _start;
}
size_t capacity() const
{
return _endofstoage - _start;
}
void reserve(size_t n)
{
size_t sz = size();
if (n > capacity())
{
T* tmp = new T[n];
//T* tmp = (T*)malloc(sizeof(T)*n);
if (_start)
{
//memcpy(tmp, _start, size()*sizeof(T));
for (size_t i = 0; i < size(); ++i)
{
tmp[i] = _start[i];
}
delete[] _start;
}
_start = tmp;
}
_finish = _start + sz;
_endofstoage = _start + n;
}
//void resize(size_t n, const T& val = T())
void resize(size_t n, T val = T())//T類型的匿名對象做缺省參數,調用T的默認構造函數
{
if (n > capacity())
{
reserve(n);
}
if (n > size())
{
while (_finish < _start + n)
{
*_finish = val;
++_finish;
}
}
else
{
_finish = _start + n;
}
}
注意點:在reservr函數中,在拷貝的時候,不可以簡單的通過memcpy函數來淺拷貝,因為當T是涉及到深淺拷貝的類型時,使用memcpy會存在深淺拷貝釋放內存空間的問題。
四、insert,erase
iterator insert(iterator pos, const T& x)
{
// 檢查參數
assert(pos >= _start && pos <= _finish);
// 擴容
// 擴容以后pos就失效了,需要更新一下
if (_finish == _endofstoage)
{
size_t n = pos - _start;
size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
reserve(newCapacity);
pos = _start + n;
}
// 挪動數據
iterator end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
--end;
}
*pos = x;
++_finish;
return pos;
}
iterator erase(iterator pos)
{
assert(pos >= _start && pos < _finish);
iterator it = pos + 1;
while (it != _finish)
{
*(it - 1) = *it;
++it;
}
--_finish;
return pos;
}
注意點:在insert函數中,如果需要擴容的話,注意擴容前后pos位置的更新,其實STL庫中也進行了這樣的更新,不更新的話位置就失效了 。
五、pop_back,push_back
void push_back(const T& x)
{
/*if (_finish == _endofstoage)
{
size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();
reserve(newcapacity);
}
*_finish = x;
_finish++;*/
insert(end(), x);
}
void pop_back()
{
erase(end() - 1);//復用
}
注意點:可以直接復用insert和erase函數。
六、operator[]
T& operator[](size_t pos)
{
assert(pos < size());
return *(_start + pos);
}
const T& operator[](size_t pos) const
{
assert(pos < size());
return *(_start + pos);
}
注意點:分別針對常對象和普通對象。
七、構造函數 析構函數 賦值重載
vector()
:_start(nullptr)
, _finish(nullptr)
, _endofstoage(nullptr)
{}
//為什么要有這個
//是為了拷貝構造的現代寫法時有一個可用的有參構造可以用
template <class InputIterator>
vector(InputIterator first, InputIterator last)
: _start(nullptr)
, _finish(nullptr)
, _endofstoage(nullptr)
{
while (first != last)
{
push_back(*first);
++first;
}
}
//n個val調用的構造函數
vector(size_t n, const T& val = T())//用一個匿名對象做缺省參數
: _start(nullptr)
, _finish(nullptr)
, _endofstoage(nullptr)
{
reserve(n);
for (size_t i = 0; i < n; ++i)
{
push_back(val);
}
}
vector(int n, const T& val = T())
: _start(nullptr)
, _finish(nullptr)
, _endofstoage(nullptr)
{
reserve(n);
for (int i = 0; i < n; ++i)
{
push_back(val);
}
}
void swap(vector<T>& v)
{
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_endofstoage, v._endofstoage);
}
//vector(const vector& v);
vector(const vector<T>& v)
: _start(nullptr)
, _finish(nullptr)
, _endofstoage(nullptr)
{
vector<T> tmp(v.begin(), v.end());
swap(tmp);
}
//vector& operator=(vector v)
vector<T>& operator=(vector<T> v)
{
swap(v);
return *this;
}
// 資源管理
~vector()
{
if (_start)
{
delete[] _start;
_start = _finish = _endofstoage = nullptr;
}
}
注意點1: 賦值重載的形參列表利用傳值傳參,調用了拷貝構造完成了深拷貝,直接交換!
注意點2:注意這種拷貝構造和賦值重載的現代寫法(請人干活,竊取果實),但必須得有對應的有參構造!
原文鏈接:https://blog.csdn.net/qq_43727529/article/details/125871697
相關推薦
- 2022-03-24 Sublime?Text3安裝Go語言相關插件gosublime時搜不到gosublime的解決方法
- 2023-05-31 Pandas.DataFrame刪除指定行和列(drop)的實現_python
- 2022-09-09 Python?OpenCV?Hough直線檢測算法的原理實現_python
- 2023-04-07 React?Mobx狀態管理工具的使用_React
- 2022-10-09 django中的自定義分頁器的實現示例_python
- 2022-02-24 Golang?strings包常用字符串操作函數_Golang
- 2023-03-23 C語言中的字符型數據與ASCII碼表_C 語言
- 2022-11-02 Python中turtle庫常用代碼匯總_python
- 最近更新
-
- 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同步修改后的遠程分支