cpp的vector模拟实现
实现的接口
Member functions:
- vector (const allocator_type& alloc = allocator_type());
- ~vector();
- vector& operator= (const vector& x);
Iterators:
- begin()
- end()
Capacity:
- size()
- resize()
- capacity()
- empty()
Element access:
- operator[]
- back()
Modifiers:
- push_back
- pop_back
- insert
- erase
- swap
- clear
特别的,学习了模板的全特化进行类型的萃取,针对深层次的深浅拷贝问题提高一定的效率。
- T是内置类型(int)或浅拷贝自定义类型(Date),他们增容或者拷贝构造中,我们用memcpy是没有问题的。但是T是深拷贝的自定义类型,他们增容或者拷贝中,我们用memcpy是有问题的。
#pragma once
#include<iostream>
#include <cassert>
namespace YCB {
//类型萃取
struct TrueType {
bool get() {
return true;
}
};
struct FalseType {
bool get() {
return false;
}
};
template<typename T>
struct TypeTraits //else的情况,表示自定义类型或者深拷贝类型
{
typedef FalseType istPodType;
};
//以下为常用基本类型特化
template<>
struct TypeTraits< bool>
{
typedef TrueType istPodType;
};
template <>
struct TypeTraits< char>
{
typedef TrueType istPodType;
};
template <>
struct TypeTraits< unsigned char >
{
typedef TrueType istPodType;
};
template <>
struct TypeTraits< short>
{
typedef TrueType istPodType;
};
template <>
struct TypeTraits< unsigned short >
{
typedef TrueType istPodType;
};
template <>
struct TypeTraits< int>
{
typedef TrueType istPodType;
};
template <>
struct TypeTraits< unsigned int >
{
typedef TrueType istPodType;
};
template <>
struct TypeTraits< long>
{
typedef TrueType istPodType;
};
template <>
struct TypeTraits< unsigned long >
{
typedef TrueType istPodType;
};
template <>
struct TypeTraits< long long >
{
typedef TrueType istPodType;
};
template <>
struct TypeTraits< unsigned long long>
{
typedef TrueType istPodType;
};
template <>
struct TypeTraits< float>
{
typedef TrueType istPodType;
};
template <>
struct TypeTraits< double>
{
typedef TrueType istPodType;
};
template <>
struct TypeTraits< long double >
{
typedef TrueType istPodType;
};
template <class _Tp>
struct TypeTraits< _Tp*>
{
typedef TrueType istPodType;
};
template<typename T>
class vector
{
public:
typedef T* iterator;
iterator begin() {
return _start;
}
iterator end() {
return _finish;
}
//构造
vector(size_t n = 0, T tmp = T())
:_start(nullptr)
, _finish(nullptr)
, _end_of_storage(nullptr)
{
reserve(n);
for (int i = 0; i < n; i++) {
_start[i] = tmp;
}
_finish = _start+n;
}
//拷贝构造(现代版)
vector(const vector<T>& A)
:_start(nullptr)
,_finish(nullptr)
,_end_of_storage(nullptr)
{
vector<T>tmp(A.size());///先初始化
this->swap(A);
if (TypeTraits<T>::istPodType().get()) {
memmove(_start, A._start, A.size() * sizeof(T));
}
else {
for (int i = 0; i < A.size(); i++) {
_start[i] = A._start[i];
}
}
}
//operator=赋值
vector<T>& operator=(const vector<T>& v) {
reserve(v.size());
_finish = _start;///视为删除.
if (TypeTraits<T>::istPodType().get()) {
memmove(_start, v._start, v.size() * sizeof(T));
}
else {
for (int i = 0; i < v.size(); i++) {
_start[i] = v._start[i];
}
}
return *this;
}
//交换函数
void swap(vector<T>& B) {
std::swap(_start, B._start);
std::swap(_finish, B._finish);
std::swap(_end_of_storage, B._end_of_storage);
}
///开辟空间
//类型萃取
void reserve(size_t n) {
if (n >= capacity()) {
T* tmp = new T[n];
assert(tmp);
size_t len = size();
//如果是内置类型(如int)
if (TypeTraits<T>::istPodType().get() ) {
memmove(tmp, _start, len * sizeof(T));
}
else {
for (int i = 0; i < len; i++) {
tmp[i] = _start[i];///调用operator=赋值(深拷贝)
}
}
delete[] _start;
_start = tmp;
_finish = _start + len;
_end_of_storage = _start + n;
}
}
void resize(size_t n, T val = T()) {
if (n > capacity()) {
///开到capacity()==n
reserve(n);
}
if (n <= size()) {
_finish = _start + n;
}
else {
size_t res = n - size();
for (int i = 0; i < res; i++) {
push_back(val);
}
_finish = _start + n;
}
}
//An iterator that points to the first of the newly inserted elements.
iterator insert(iterator pos, const T& val) {
if (size() == capacity()) {
reserve((capacity() == 0 ? 4 : capacity() * 2)); ///防止多此扩容
}
iterator tmp = _finish ;
while (tmp > pos) {
*tmp = *(tmp - 1);
tmp--;
}
*pos = val;
_finish++;
return pos;
}
iterator erase(iterator pos) {
assert(pos < _finish&& pos >=_start);
iterator tmp = pos;
while (tmp +1 < _finish) {
*tmp = *(tmp + 1);
tmp++;
}
_finish--;
assert(_finish >= _start);
//An iterator pointing to the new location of the element that followed the last element erased by the function call.
return pos;
}
//[first,last)
iterator erase(iterator first, iterator last) {
assert(first >= _start);
iterator pos = first;
if (last >= _finish) {
_finish = first;
}
else {
iterator tmp= last;
while (tmp != _finish) {
_start[first] = _start[tmp];
first++;
tmp++;
}
_finish = first;
}
return pos;
}
void push_back(const T& val) {
if (_finish == _end_of_storage) reserve( (capacity() == 0 ? 4 : capacity() * 2) );//减少扩容次数
*_finish = val;
_finish++;
}
void pop_back(){
_finish--;
assert(_finish>=_start);
}
void clear() {
_finish = _start;
}
bool empty() const {
return (_start == _finish);
}
size_t size() const {
return _finish - _start;
}
size_t capacity() const {
return _end_of_storage - _start;
}
T& back() {
if (_start == _finish) return _start[0];
else return *(_finish - 1);
}
T& operator[](const size_t& pos) {
assert(pos < size());
return _start[pos];
}
T& operator[](const size_t& pos) const {
assert(pos < size());
return _start[pos];
}
//析构
~vector() {
delete[] _start;
_finish = _end_of_storage = nullptr;
}
private:
T* _start;
T* _finish;
T* _end_of_storage;
};
void test_vector1() {
vector<int>v1;
vector<int>v2(5,0);
vector<double>v3(10, 2.3);
cout << v1.size() << endl;
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}cout << endl;
cout << v2.size() << endl;
for (int i = 0; i < v2.size(); i++) {
v2[i] += 1;
cout << v2[i] << " ";
}cout << endl;
cout << v3.size() << endl;
for (int i = 0; i < v3.size(); i++) {
cout << v3[i] << " ";
}cout << endl;
vector<int>v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
vector<int>::iterator it = v.begin();
while (it != v.end()) {
*it += 1;
cout << *it << endl;
++it;
}
}
void test_vector2() {
vector<string>v1(2, std::string("zstu"));
//vector<string>v2(4, "http://www.zstu.edu.cn/");
cout << v1.size() << endl;
for (auto &i : v1) {
cout << i << " ";
}cout << endl;
/*cout << v2.size() << endl;
for (auto& i : v2) {
cout << i << " ";
}cout << endl;*/
v1.push_back("zzzzzzzzzzzzzzzzzz");
v1.push_back("ssssssssssssssssss");
v1.push_back("tttttttttttttttttt");
v1.push_back("uuuuuuuuuuuuuuuuuu");
cout << v1.size() << endl;
vector<string>::iterator it = v1.begin();
while (it != v1.end())
{
cout << (*it) << " ";
cout << endl;
it++;
}cout << endl;
}
void test_vector3() {
vector<int>v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.pop_back();
v.pop_back();
cout << v.size() << " " << v.capacity() << endl;
for (auto &i : v) {
cout << i << " ";
}cout << endl;
v.resize(3);
cout << v.size() << " " << v.capacity() << endl;
for (auto& i : v) {
cout << i << " ";
}cout << endl;
v.resize(6, 1);
cout << v.size() << " " << v.capacity() << endl;
for (auto& i : v) {
cout << i << " ";
}cout << endl;
v.resize(10, 2);
cout << v.size() << " " << v.capacity() << endl;
for (auto& i : v) {
cout << i << " ";
}cout << endl;
}
void test_vector4() {
vector<int>v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
cout << v.size() << " " << v.capacity() << endl;
for (auto& i : v) {
cout << i << " ";
}cout << endl;
vector<int>::iterator pos = find(v.begin(), v.end(), 3);
cout << (pos - v.begin()) << endl;
//在pos--3的之前插入
v.insert(pos, 30);
cout << v.size() << " " << v.capacity() << endl;
for (auto& i : v) {
cout << i << " ";
}cout << endl;
cout << (pos - v.begin()) << endl;
cout << (*pos) << endl;
//insert以后,pos就是失效了
//1.pos指向的位置的意义变了,pos不是指向3
//2.pos成了野指针
}
void test_vector5() {
vector<int>v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
vector<int>::iterator it = v.begin();
while (it != v.end())
{
if (*it % 2 == 0) {
v.erase(it);
}
else ++it;
}
cout << v.size() << " " << v.capacity() << endl;
for (auto i : v) {
cout << i << " ";
}cout << endl;
}
}