網(wǎng)站首頁 編程語言 正文
一、基礎(chǔ)框架
template<class T>
class vector
{
public:
typedef T* iterator;
typedef const T* const_iterator;
private:
iterator _start;//指向第一個元素
iterator _finish;//指向最后一個元素的下一個位置
iterator _endofstoage;//容量
};
二、迭代器實現(xiàn)
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類型的匿名對象做缺省參數(shù),調(diào)用T的默認(rèn)構(gòu)造函數(shù)
{
if (n > capacity())
{
reserve(n);
}
if (n > size())
{
while (_finish < _start + n)
{
*_finish = val;
++_finish;
}
}
else
{
_finish = _start + n;
}
}
注意點:在reservr函數(shù)中,在拷貝的時候,不可以簡單的通過memcpy函數(shù)來淺拷貝,因為當(dāng)T是涉及到深淺拷貝的類型時,使用memcpy會存在深淺拷貝釋放內(nèi)存空間的問題。
四、insert,erase
iterator insert(iterator pos, const T& x)
{
// 檢查參數(shù)
assert(pos >= _start && pos <= _finish);
// 擴(kuò)容
// 擴(kuò)容以后pos就失效了,需要更新一下
if (_finish == _endofstoage)
{
size_t n = pos - _start;
size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
reserve(newCapacity);
pos = _start + n;
}
// 挪動數(shù)據(jù)
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函數(shù)中,如果需要擴(kuò)容的話,注意擴(kuò)容前后pos位置的更新,其實STL庫中也進(jìn)行了這樣的更新,不更新的話位置就失效了 。
五、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);//復(fù)用
}
注意點:可以直接復(fù)用insert和erase函數(shù)。
六、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);
}
注意點:分別針對常對象和普通對象。
七、構(gòu)造函數(shù) 析構(gòu)函數(shù) 賦值重載
vector()
:_start(nullptr)
, _finish(nullptr)
, _endofstoage(nullptr)
{}
//為什么要有這個
//是為了拷貝構(gòu)造的現(xiàn)代寫法時有一個可用的有參構(gòu)造可以用
template <class InputIterator>
vector(InputIterator first, InputIterator last)
: _start(nullptr)
, _finish(nullptr)
, _endofstoage(nullptr)
{
while (first != last)
{
push_back(*first);
++first;
}
}
//n個val調(diào)用的構(gòu)造函數(shù)
vector(size_t n, const T& val = T())//用一個匿名對象做缺省參數(shù)
: _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: 賦值重載的形參列表利用傳值傳參,調(diào)用了拷貝構(gòu)造完成了深拷貝,直接交換!
注意點2:注意這種拷貝構(gòu)造和賦值重載的現(xiàn)代寫法(請人干活,竊取果實),但必須得有對應(yīng)的有參構(gòu)造!
原文鏈接:https://blog.csdn.net/qq_43727529/article/details/125871697
相關(guān)推薦
- 2022-04-24 Python大數(shù)據(jù)用Numpy?Array的原因解讀_python
- 2022-02-22 rcp異常org.eclipse.swt.SWTException: Invalid thread
- 2022-06-08 FreeRTOS動態(tài)內(nèi)存分配管理heap_1示例_操作系統(tǒng)
- 2022-10-01 使用python+Flask實現(xiàn)日志在web網(wǎng)頁實時更新顯示_python
- 2022-12-22 如何使用python獲取現(xiàn)在的日期與時間_python
- 2022-12-23 Python中的文件輸入輸出問題_python
- 2022-10-06 Android?Jetpack庫重要組件WorkManager的使用_Android
- 2022-04-08 C++中成員函數(shù)和友元函數(shù)的使用及區(qū)別詳解_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支