简单讲一下自己实现的一些注意的点。
难点有两个,一个是reserve函数扩容,关于浅拷贝(用memcpy浅)的解决问题,博主用了赋值来解决(调用vector<T>中的T类型的赋值)。
另一个是关于insert和erase函数的返回值的思考,(还是扩容或(缩容/删除最后一个val)所造成的迭代器失效问题)
除此之外并无太多难点。
源码:
vector.h
#pragma once
#include<iostream>
namespace bit
{
template<class T>
class vector
{
public:
// Vector的迭代器是一个原生指针
typedef T* iterator;
typedef const T* const_iterator;
iterator begin() {
return _start;
}
iterator end() {
return _finish;
}
const_iterator cbegin() const{
return _start;
}
const_iterator cend() const {
return _finish;
}
// construct and destroy
vector()
:_start(nullptr)//每个构造都要这样,可以搞省缺值的
,_finish(nullptr)
,_endOfStorage(nullptr)
{}
vector(int n, const T& value = T())//只能搞push_back的?
:_start(nullptr)
,_finish(nullptr)
,_endOfStorage(nullptr)
{
reserve(n);
for (int i = 0; i < n; ++i) {
push_back(value);
}
}
template<class InputIterator>
vector(InputIterator first, InputIterator last)
:_start(nullptr)
, _finish(nullptr)
, _endOfStorage(nullptr)
{
while (first != last) {
push_back(*first);
++first;
}
}
vector(const vector<T>& v)
:_start(new T [v._finish - v._start])
,_finish(_start + (v._finish - v._start))
,_endOfStorage(_finish)
{
//浅
//std::memcpy(_start, v._start, sizeof(T) * (v._finish - v._start));
for (int i = 0; i < size(); ++i) {
(*this)[i] = v[i];
}
}
vector<T>& operator= (vector<T> v) {
swap(*this, v);
return *this;
}
~vector() {
delete[] _start;
_start = _finish = _endOfStorage = nullptr;
}
// capacity
size_t size() const {
return _finish - _start;
}
size_t capacity() const {
return _endOfStorage - _start;
}
//需要<>里的类型支持swap
void reserve(size_t n) {
if (n <= capacity()) { //算是双重保障
return;
}
vector<T> v1;
v1._start = new T[n];
v1._finish = v1._start + size();
v1._endOfStorage = v1._start + n;
//std::memcpy(v1._start, _start, sizeof(T) * size());
for (int i = 0; i < size(); ++i) {
v1[i] = (*this)[i];
}
swap(v1);//这个类里的swap_vector
}
void resize(size_t n, const T& value = T()) {
if (size() >= n) {
_finish = _start + n;
}
else {
while (_finish != _start + n) {
push_back(value);
}
}
}
///access///
T& operator[](size_t pos) {//关于我这里使用*的疑问?
return *(_start + pos);
}
const T& operator[](size_t pos)const {
return *(_start + pos);
}
///modify/
void push_back(const T& x) {
//if (_endOfStorage == _finish) {
// size_t newSize = capacity() == 0 ? 4 : capacity() * 2;
// reserve(newSize);
//}
//*_finish = x;
//++_finish;
insert(_finish, x);
}
void pop_back() {
if (_start == _finish) {
return;
}
--_finish;
}
void swap(vector<T>& v) {
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_endOfStorage, v._endOfStorage);
}
//当作这个pos是迭代器,而不是下标
iterator insert(iterator pos, const T& x) {
if (pos > _finish || pos < _start) {
exit(1);
}//该用assert的,可以知道哪里错了
if (_finish == _endOfStorage) {
int startPosSzie = pos - _start;
size_t newSize = capacity() == 0 ? 4 : capacity() * 2;
reserve(newSize);//可以改进,但懒
pos = _start + startPosSzie;
}
iterator it = _finish;
while (it != pos) {
*it = *(it - 1);
--it;
}
*pos = x;
++_finish;
return pos;
}
iterator erase(iterator pos) {
if (pos >= _finish || pos < _start) {
exit(1);
}//size() == 0排出去了
iterator it = pos + 1;
while (it != _finish) {
*(it - 1) = *it;
++it;
}
--_finish;
return pos;
}
private:
iterator _start; // 指向数据块的开始
iterator _finish; // 指向有效数据的尾
iterator _endOfStorage; // 指向存储容量的尾
};
}
test.cpp:
#define _CRT_SECURE_NO_WARNINGS 1
#include"vector.h"
#include<string>
using namespace bit;
void show(vector<int>& v) {
//for (auto e : v) {
// std::cout << e << ' ' << std::endl;
//}
for (int i = 0; i < v.size(); ++i) {
std::cout << v[i] << ' ';
}
std::cout << ' ' << std::endl;
}
void test01() {
vector<int> v1;
//vector<int> v2 = { 1, 2, 7, 3, 4, 5, 6 };//不支持
vector<int> v3(10, 0);
int a[] = { 1, 2, 7, 3, 4, 5, 6 };
vector<int> v4(a, a + (sizeof(a)/ sizeof(int)));
vector<int> v5(v4);
show(v1);
show(v3);
show(v4);
show(v5);
}
void test02(){
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
v1.push_back(6);
show(v1);
v1.resize(2, 8);
show(v1);
v1.resize(8, 8);
show(v1);
}
void test03() {
vector<std::string> v1;
v1.push_back("1010101010012222");
v1.push_back("1010101010012222");
v1.push_back("1010101010012222");
v1.push_back("1010101010012222");
v1.push_back("1010101010012222");
v1.push_back("1010101010012222");
}
int main()
{
test02();
return 0;
}