0
点赞
收藏
分享

微信扫一扫

命名空间——初识c++

蓝哆啦呀 1天前 阅读 2

目录

1. vector与顺序表

2. vector的使用

2.1 默认成员函数

1. 构造与拷贝构造

//默认构造,内容为空
vector<int> v1;

//指定数据内容与个数构造
vector<int> v2(3,100);

//迭代器区间构造
vector<int> v3(v2.begin(), v2.end());

//使用列表构造
vector<int> v4({1,2,3,4,5});

//拷贝构造
vector<int> v5(v4);

2. operator=赋值运算符重载

vector<int> v1(3, 100);
vector<int> v2;
//给已经存在的对象赋值
v2 = v1;

//当使用赋值运算符对还没有产生的对象赋值时,会调用拷贝构造
vector<int> v3 = v1;

2.2 vector的迭代器

//正向反向迭代器
vector<int> v1;
vector<int>::iterator it1 = v1.begin();
vector<int>::iterator it2 = v2.end();

vector<int>::reverse_iterator it3 = v3.rbegin();
vector<int>::reverse_iterator it4 = v4.rend();

//const修饰的正反向迭代器
vector<int>::const_iterator it5 = v5.cbegin();
vector<int>::const_iterator it6 = v6.cend();

vector<int>::const_reverse_iterator it7 = v7.crbegin();
vector<int>::const_reverse_iterator it7 = v8.crend();

2.3 容量相关成员函数

1. 容量大小

vector<int> v1(3, 100);

//当前存储的数据个数
cout << v1.size() << endl;

//理论上最多能够存储的数据个数,无参考意义
cout << v1.max_size() << endl;

//当前vector的容量
cout << v1.capacity() << endl;

//检测当前vector是否为空,无存储元素
cout << v1.empty() << endl;

2. 扩容与缩容

vector<int> v2(3,100);

//将当前vector扩容至指定大小,1.5被扩容
v2.reserve(10);

//将当前vector扩容至指定大小,再将扩容出的部分用指定数填满
//vector长度跟随增长,未指定时,默认使用0填充
v2.resize(20);

//缩容,将当前大于有效数据长度的部分缩减
//将缩小当前数据的长度
v2.shrink_to_fit();

2.4 遍历访问方式

vector<int> v1(5,100);

//operator[]运算符重载
//报警告
v1[0];

//抛异常
v1.at[1];

//返回vector的首尾元素
v1.front();
v.back();

2.5 vector的修改操作

1. 插入,赋值操作

vector<int> v1(5, 100);
vector<int> v2;
//assign
//指定用多少个什么数赋值
v2.assgin(4,100);
//使用迭代器区间赋值
v2.assgin(v1.begin(), v2.end());

//尾插
v2.push_back(10);

//随机插入
//在指定位置(迭代器表示),插入一个数
v2.insert(v2.begin(), 10);

//在指定迭代器位置,插入n个数
v2.insert(v2.begin(), 3, 10);

//在指定迭代器位置插入一段迭代器区间
v2.insert(v2.begin(), v1.begin(), v1.end());

2. 删除操作

vector<int> v1(10, 100);

//尾删
v1.pop_back();

//删除指定迭代器位置的数据
v1.erase(v1.begin());

//删除指定迭代器区间的数据
v1.erase(v1.begin(), v1.begin() + 3);

//清空vector
v1.clear();

//补充:成员函数swap
vector<int> v2(10, 9);

v1.swap(v2);

3. vector的自实现

3.1 自实现功能

3.2 vector的结构与自实现的逻辑

在这里插入图片描述

在这里插入图片描述

3.3 自实现vector功能接口

1. 成员变量与迭代器

template<class T>
class vector
{
public:
	typedef T* iterator;
	typedef const T* const_iterator;

	//迭代器
	iterator begin()
	{
		return _start;
	}

	iterator begin() const
	{
		return _start;
	}

	iterator end()
	{
		return _finish;
	}

	iterator end() const
	{
		return _finish;
	}

private:
	iterator _start = nullptr;
	iterator _finish = nullptr;
	iterator _endofstorage = nullptr;	
};

2. 容量相关

size_t size()
{
	return _finish - _start;
}

size_t capacity()
{
	return _endofstorage - _start;
}

3. 扩容与插入删除

void reserve(size_t n)
{
	if (n > capacity())
	{
		//开辟空间
		T* tmp = new T[n];
		int old = _finish - _start;

		//检测是否需要赋值
		if (_start)
		{
			for (int i = 0; i < old; i++)
			{
				tmp[i] = _start[i];
			}

			//释放旧空间
			delete[] _start;
		}
		
		//直接调用capacity与size()会导致报错
		//扩容后指针失效
		_start = tmp;
		_finish = _start + old;
		_endofstorage = _start + n;
	}
}

在这里插入图片描述

void push_back(const T& val)
{
	if (_finish == _endofstorage)
	{
		int newcapacity = capacity() == 0 ? 4 : 2 * capacity();
		reserve(newcapacity);
	}

	*_finish = val;
	_finish++;
}
//C++中为内置类型也添加了构造
//double 0.0,char '\0',int 0
void resize(size_t n, T val = T())
{
	if(n > size())
	{
		//扩容
		reserve(n);
		//填值
		while(_finish < _start + n)
		{
			*_finish = val;
			++_finish;
		}
	}
	else
	{
		//缩容
		_finish = _start + n;
	}
}
void pop_back()
{
	assert(size() > 0);

	--_finish;
}

4. 默认成员函数

//构造
vector()
{}

//拷贝构造
vector(const vector<T>& v)
{
	auto it = v.begin();
	//范围for
	while (it < v.end())
	{
		push_back(*it);
		it++;
	}
}
void swap(vector<T>& v)
{
	std::swap(_start, v._start);
	std::swap(_finish, v._finish);
	std::swap(_endofstorage, v._endofstorage);
}

//现代写法
vector<T>& operator=(vector<T> v)
{
	swap(v);

	return *this;
}
template<class Inputiterator>
vector(Inputiterator it1, Inputiterator it2)
{
	//其他数据结构的内存空间可能不连续
	while (it1 != it2)
	{
		push_back(*it1);
		it1++;
	}
}
//n个指定值构造
vector(size_t n, T val = T())
{
	//直接复用resize
	resize(n, val);
}

//两个参数都为int时,保证调用此构造
vector(int n, T val = T())
{
	resize(n, val);
}
~vector()
{
	if (_start)
	{
		delete[] _start;
	}

	_start = _finish = _endofstorage = nullptr;
}

5. 迭代器失效,深浅拷贝与erase,insert

//在pos位置插入一个数
iterator insert(iterator pos, T val)
{
	assert(pos >= _start && pos <= _finish);

	int old = pos - _start;
	//扩容后迭代器失效
	if (_finish == _endofstorage)
	{
		int newcapacity = capacity() == 0 ? 4 : 2 * capacity();
		reserve(newcapacity);
	}

	//避免自定义类型浅拷贝,不能使用memmove等函数
	//向后依次挪移,使用存储数据类型的赋值重载
	//迭代器插入没有下标插入size_t类型的特殊处理
	pos = _start + old;
	auto end = _finish - 1;
	while (end >= pos)
	{
		*(end + 1) = *end ;
		end--;
	}

	*pos = val;
	_finish++;

	//防止迭代器失效,可以使用插入与++分离的方式
	//不能保证不扩容
	return pos;
}

扩容导致的迭代器失效:
在这里插入图片描述

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

	//迭代器失效,memmove浅拷贝
	auto it = pos + 1;
	while (it < _finish)
	{
		*(it - 1) = *it;
		it++;
	}

	_finish--;

	return pos;
}

6. operator[]的运算符重载

vector<T>& operator[](size_t pos)
{
	assert(pos < _finish - _start);

	return _start + pos;
}

const vector<T>& operator[](size_t pos) const
{
	assert(pos < _finish - _start);

	return _start + pos;
}
举报

相关推荐

0 条评论