vector的相关内容介绍及模拟实现

一.内容介绍

1.vector是一个模板,不支持流插入和流提取,因为它支持多种方式的输出,不需要局限于流提取的方式

2.关于vector所涉及的函数接口与string类的用法类似,有兴趣可参考小编的另一篇博客

3.vector的迭代器失效问题

1>类似于野指针:原来指向的空间已经被销毁,具体可参考后续inser中扩容后原空间释放,在新空间中,指针位置改变的例子

2>位置意义已经改变:具体可参照erase中删去一个数据后,pos指向的位置不变,但该位置上的内容已经改变

4.vector中的二维数组

例:int array[10][5]

      vector<int> v(5,1);//v是一个含有5个int类型数据的数组

       vector<vector<int>> vv(10,0);//vv是一个含有10个vector<int>类型的数组

二.模拟实现

1.由于vector是类模板,不可以进行声明和定义分离,否则会发生链接错误

2.vector的成员变量:

template<class T>
class vector
{
public:
	typedef T* iterator;
private:
	iterator _start;
	iterator _finish;
	iterator _end_of_storage;
};

3.size()   和  capacity()

size_t size() const
{
	return _finish - _start;
}

size_t capacity() const
{
	return _end_of_storage - _start;
}

4.reverse:扩容/预留空间

1>需要注意的一点是要记录原来的有效字符个数,避免之后计算_finish的指向时调用size()时出现两个指针分别位于两块空间内的情况

2>代码实现

void reverse(size_t n)
{
	if (n > capacity())
	{
		//记录原来的有效字符个数,避免释放之后调用size()时出现两个指针分别位于两块空间内
		size_t old_size = size();
		iterator tmp = new T[n];
        //对内置类型可用memcpy
		memcpy(tmp, _start, sizeof(T) * old_size);
		delete _start;

		_start = tmp;
		_finish = _start + old_size;
		_end_of_storage = _start + old_size;
	}
}

5.迭代器的实现

typedef T* iterator;
typedef const T* const_iterator;

const_iterator begin() const
{
	return _start;
}

const_iterator end() const
{
	return _finish;
}

iterator begin()
{
	return _start;
}

iterator end()
{
	return _finish;
}

6.operator[]:下标访问

T& operator[](size_t i)
{
	assert(i < size());
	return *(_start + i);
}

7.pop_back

bool empty()
{
	return _start == _finish;
}

void pop_back()
{
	assert(!empty());
	--_finish;
}

8.print_vector函数模板的实现

1>注意编译器不能在没有实例化的类模板里取东西,因为它无法区分const_iterator是类型还是静态成员变量,所以vector<T>::const_iterator it前面要加上typename表明它是类型,或者直接用auto让编译器自己去判断it的类型

2>代码实现

template<class T>
void print_vector(const vector<T>& v)
{
	//auto it=v.begin();
	typename vector<T>::const_iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it<<" ";
		++it;
	}
	cout << endl;
}

9.insert

void insert(iterator pos, const T& x)
{
    assert(pos <= _finish);
    assert(pos>=_start);
    if (_finish==_end_of_storage)
    {
	   reverse(capacity()==0?4:2*capacity());
    }
	iterator end = _finish - 1;
	while (end >= pos)
	{
		*(end + 1) = *end;
		--end;
	}
	*pos = x;
	++_finish;
}

10.erase

1>代码实现

void erase(iterator pos)
{
	assert(pos >= _start);
	assert(pos < _finish);

	iterator it = pos + 1;
	while (it != _finish)
	{
		*(it - 1) = *it;
		++it;
	}
	--_finish;
}

2>注意在用遍历法删除数组中某些数字时,需注意新移到原pos位置的数据是否符合删除要求,下面小编以删除数组中2的倍数为例简单介绍一下:

vector<int>::iterator it = v.begin();
while (it != v.end())
{
	if (*it % 2 == 0)
	{
		v.erase(it);
	}
	else
	{
		++it;
	}
}

11.resize

void resize(size_t n, T val = T())
{
	if (n < size())
	{
		_finish = _start + n;
	}
	else
	{
		if (n > capacity())
		{
			reserve(n);
		}
		while (_finish < _start + n)
		{
			*_finish = val;
			++_finish;
		}
	}
}

12.构造,拷贝构造,析构


		/*vector()
		{}*/
		//C++11 强制生成默认构造
		vector() = default;

		//v1(v2)
		vector(const vector<T>& v)
		{
			//避免扩容,提高效率
			reserve(v.size());
			for (auto& e : v)
			{
				push_back(e);
			}
		}

		~vector()
		{
			if (_start != nullptr)
			{
				delete[] _start;
				_start = _finish = _end_of_storage = nullptr;
			}
		}

13.operator=

1>普通写法

void clear()
{
	_finish = _start;
}

//v1=v2
vector<T>& operator=(const vector<T>& v)
{
	clear();
	reserve(v.size());
	for (auto& e : v)
	{
		push_back(e);
	}
	return *this;
}

2>现代写法

void swap(vector<T>& v)
{
	std::swap(_start, v._start);
	std::swap(_finish, v._finish);
	std::swap(_end_of_storage, v._end_of_storage);
}

vector<T>& operator=(vector<T>& v)
{
	swap(v);
	return *this;
}

14.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值