文章目錄
- 1.模擬實作前須知知識點
- 1.1普通類和模板類的良好撰寫習慣
- 1.2vector中的引數含義
- 1.3空間的開辟注意事項
- 1.3.1開空間不能用malloc/realloc
- 1.3.2注意深淺拷貝
- 1.4巧妙利用{}作用域,呼叫解構式
- 1.5迭代器失效場景
- 2.實作程序
- 3.代碼
1.模擬實作前須知知識點
1.1普通類和模板類的良好撰寫習慣
1.模板類
使用類模板時,宣告和定義不要分離,分離也要放在同一個檔案,否則會導致鏈接錯誤
由于宣告和定義必須放在同一檔案,所以很多時候都將.h檔案寫成.hpp檔案,表示我使用的是模板類,并且宣告和定義都不會分離
2.普通類
平時我們應該將宣告和定義分離,這樣可以更好的看見類的整體框架
并且我們可以將代碼短小的函式放在類里面,讓它默認成為行內函式
1.2vector中的引數含義

1.3空間的開辟注意事項
1.3.1開空間不能用malloc/realloc

1.3.2注意深淺拷貝

1.4巧妙利用{}作用域,呼叫解構式

1.5迭代器失效場景


2.實作程序
一個類的默認有六種成員函式,我們模擬實作的時候一般都是實作它的構造、拷貝構造、賦值運算子多載、解構式,取地址多載默認的就夠用了;
在實作了基本的成員函式之后,應該轉移到增刪查改的思路上面去模擬實作,像vector的增有push_back和insert刪有erase和push_pop,查是庫里面公用的find,改則是多載[]
在實作上述程序之中,會發現容量也需要改變,因此我們還需要實作reserve和resize,同時也需要將迭代器進行重定義,vector的迭代器就是它的原生指標
在此在之外,我們通常會需要獲得空間內部的大小和有效元素的個數,因此需要size和capacity介面,在外部的時候我們很有可能需要訪問私有成員變數,因此又可以提供begin和end介面
在上述實作中,如果不需要改變的地方盡量的使用const,擴大接收范圍,如果可以場景使用參考的話,盡量使用參考,降低拷貝的消耗
3.代碼
#pragma once
#include <assert.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
#include <string>
namespace mv
{
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()//建構式說明,vector出來一個物件之后,第一件就是給它開空間
:_start(nullptr),
_finish(nullptr),
_end_of_storge(nullptr)
{}
template<class InputIterator>//模板函式
vector(InputIterator first, InputIterator last)
: _start(nullptr),
_finish(nullptr),
_end_of_storge(nullptr)
{
reserve(last - first);//開辟空間
while (first != last)
{
push_back(*first);
first++;
}
}
void swap(vector<T> &x)
{
std::swap(_start, x._start);
std::swap(_finish, x._finish);
std::swap(_end_of_storge, x._end_of_storge);
}
vector(const vector<T> &x)
:_start(nullptr),
_finish(nullptr),
_end_of_storge(nullptr)
{
vector<T> temp(x.begin(), x.end());
swap(temp);
}
vector<T> &operator =(vector<T> x)
{
swap(x);
return *this;
}
T &operator[](size_t index)
{
assert(index<size());
return _start[index];
}
T &operator[](size_t index)const//const型別呼叫const
{
assert(index<size());
return _start[index];
}
~vector()
{
delete[]_start;
_start = _finish = _end_of_storge = nullptr;
}
size_t capacity()const
{
return _end_of_storge - _start;
}
size_t size()const
{
return _finish - _start;
}
//void reserve(size_t n) //淺拷貝,只適用于內置
//{
// if (n>capacity())
// {
//
// T *temp = new T[n];
// size_t old_size = size();//臨時保存一份,避免失效
// memcpy(temp, _start, size()*sizeof(T));
// //delete[] _start;
// _start = temp;
// _finish = _start + old_size;
// _end_of_storge = _start + n;
// temp = nullptr;
// }
//}
void reserve(size_t n)
{
if (n > capacity())
{
iterator temp = new T[n];
size_t old_size = size();//大小臨時記錄一下
iterator begin_start = _start;
iterator begin_temp=temp;
while (begin_start != _finish)
{
*begin_temp= *begin_start;//深拷貝一份
//往后挪動
begin_start++;
begin_temp++;
}
delete[] _start;//釋放原來的空間
_start = temp;//指向新的空間
temp = nullptr;//防止析構自定義型別
_finish = _start + old_size;//不直接使用size是因為防止迭代器失效
_end_of_storge = _start + n;
}
}
void check_capacity()
{
if (_finish >= _end_of_storge)
{
size_t newsize = capacity() == 0 ? 4 : 2 * capacity();//如果為0,則擴容4個,否則擴容2倍
reserve(newsize);
}
}
void push_back(const T &x)
{
check_capacity();
*_finish = x;
_finish++;
}
void pop_back()
{
assert(_finish>_start);
_finish--;
}
void resize(size_t newsize, const T &x=T())//呼叫匿名物件,具有常性,需要加上const
{
if (newsize>capacity())
{
reserve(newsize);//擴容
}
if (newsize<size())
_finish = _start + newsize;
else
{
while (_finish != _start + newsize)
{
*_finish = x;
_finish++;
}
}
}
iterator insert(iterator pos, const T&x)
{
assert(pos <= _finish&&pos >= _start);
size_t inpos = pos - _start;//保存一份相對位置,防止迭代器失效
check_capacity();
pos = _start + inpos;
iterator last = _finish;
while (last != pos)//往后挪動
{
*last = *(last - 1);
last--;
}
*pos = x;
_finish++;
return pos;//結局和迭代器失效問題
}
void Print()
{
iterator start = _start;
while (start != _finish)
{
cout << *start << " ";
start++;
}
cout << endl;
}
iterator erase(iterator pos)
{
assert(pos >= _start&&pos < _finish);
iterator temp_pos = pos;
while (pos < _finish-1)
{
*pos = *(pos + 1);
pos++;
}
_finish--;
return temp_pos;
}
private:
iterator _start;
iterator _finish;
iterator _end_of_storge;
};
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/273591.html
標籤:其他
上一篇:java 考試系統 在線學習 視頻直播 人臉識別 springboot框架 前后分離 PC和手機端
下一篇:新版的ARMv9到底牛在哪?
