VECTOR

STL 中vector

一、vector简介

1.vector是表示可以改变大小的数组的序列容器。

底层数据结构:动态开辟的数组,每次以原来空间的1.5倍进行扩容。

添加操作

vector<int>  a;
a.push_back(20);//再末尾添加元素
a.insert(it,20);//it迭代器指向的位置添加一个元素20  O(n) 有可能导致容器扩容,插入一个元素,后边所有的的元素都要向后挪动一个位置

可以简单理解下图

容器中进行对象的构造和析构1,内存开辟和释放,都是通过容器的空间配置器allocator(负责内存开辟)和deallocator(负责内存释放),construct(对象构造),destory(对象析构) 。

2.删除操作

 a.pop_back();//从末尾删除   时间复杂度O(1)
 a.erase(it);//删除it迭代器指向的元素
删除之后,删除点之后的元素都得向前挪动

3.访问数据

1.使用for循环,由下标访问;

2.使用at()访问

3.使用迭代器访问,可以理解为面向对象的指针

4.常性迭代器,无法改变值,只可取值

5.基于范围for循环,这里使用的引用,如果是变量,每一步都需要拷贝构造

示例

class Object
{
private:
	int num;
public:
	Object(int x = 0) : num(x)
	{
		cout << "Create Object: " << this << endl;
	}
	~Object()
	{
		cout << "Destroy Object: " << this << endl;
	}
	Object(const Object& obj) :num(obj.num)
	{
	}
	Object& operator=(const Object& obj)
	{
		if (this != &obj)
		{
			num = obj.num;
		}
		return *this;
	}
	int& Value() { return num; }
	const int& Value()const { return num; }
};
int main()
{
	vector<Object> vec = { Object(10),Object(20),Object(30) };
	for (int i = 0; i < vec.size(); ++i)
	{
		cout << vec[i].Value() << endl;
	}
	for (int i = 0; i < vec.capacity(); ++i)
	{
		cout << vec.at(i).Value() << endl;
	}
	vector<Object>::iterator it = vec.begin();
	for (; it != vec.end(); ++it)
	{
		cout << it->Value() << " ";
		it->Value() += 10;
		cout << it->Value() << endl;
	}
	vector<Object>::const_iterator it2 = vec.begin();
	for (; it2 != vec.end(); ++it2)
	{
		cout <<it2->Value() << " ";
	}
	cout << endl;
	for (auto& x : vec)
	{
		cout << x.Value() << " " << endl;
	}
	cout << endl;

	return 0;


}

 4.reserve()预留存储空间

所需参数

void reserve(size_type new_cap);

 增加vector的容量到大于或等于new_cap,若new_cap大于当前capacity(),则重新分配空间;

如果小于capacity(),则不处理

int main()
{
	vector<Object>vec = { Object(10),Object(20),Object(30) };
	cout << vec.size() << endl;
	cout << vec.capacity() << endl;

	vec.reserve(10);
	cout << vec.size() << endl;
	cout << vec.capacity() << endl;
	return 0;
}

迭代器失效问题

在使用reserve()时,new_cap大于capacity,需要重新申请空间,那么迭代器的指向原有空间会被析构,造成迭代器失效。

需要注意的是reserve()函数给vector预分配储存大小,但没有给这段内存初始化,导致vector可以利用这段存储空间,但并不能有效访问这些空间,如果访问就会出现越界现象,导致程序奔溃

 5.resize()改变容器大小,并且创建对象

如果resize()的参数大于原来的capacity,那么

           1.重新申请空间

           2.再对申请的额外的空间初始化为0;

           3.把原数据拷贝过来; 

int main()
{
	vector<Object>vec = { Object(10),Object(20),Object(30) };
	cout << vec.size() << endl;
	cout << vec.capacity() << endl;

	vec.resize(10);
	cout << vec.size() << endl;
	cout << vec.capacity() << endl;
	return 0;
}

6.assign()

void  assign(size_t count,_Ty());

 此函数与上面两个函数不同之处在于

            1.先构造一个目标对象;

            2.析构之前对象

            3.拷贝构造这个对象count次

            4.析构目标对象

int main()
{
	vector<Object>vec = { Object(10),Object(20),Object(30) };
	cout << vec.size() << endl;
	cout << vec.capacity() << endl;

	vec.assign(10,Object(100));
	cout << vec.size() << endl;
	cout << vec.capacity() << endl;
	return 0;
}

 7.push_back()和emplace_back()

     push_back()在容器末尾插入一个元素,如果插入时空间不足遇到扩容问题,就会造成迭代器失效。

示例

在初始化后迭代器还能使用,,再push_back()后空间扩容,之前的对象会被析构掉,迭代器失效。

int main()
{
	vector<Object>vec = { Object(10),Object(20),Object(30) };
	cout << vec.size() << endl;
	cout << vec.capacity() << endl;
	vector<Object>::iterator it = vec.begin();
	cout << it->Value() << endl;
	vec.push_back(Object(40));
	cout << it->Value() << endl;
	cout << vec.size() << endl;
	cout << vec.capacity() << endl;

	return 0;
}

要是迭代器正常使用,可以在一开始就给容器增容。

示例 

int main()
{
	vector<Object>vec;
	vec.reserve(10);
	vec= { Object(10),Object(20),Object(30) };
	
	vector<Object>::iterator it = vec.begin();
	cout << it->Value() << endl;
	vec.push_back(Object(40));
	cout << it->Value() << endl;

	return 0;
}

emplace_back()原位构造

int main()
{
	vector<Object>vec;
	vec.reserve(10);
	vec= { Object(10),Object(20),Object(30) };
	
	vector<Object>::iterator it = vec.begin();
	cout << it->Value() << endl;
	vec.emplace_back(Object(40));
	cout << it->Value() << endl;

	return 0;
}

 

区别:

push_back()构造时,是先构造一个无名对象,再对其拷贝构造后插入末尾,然后析构无名对象。

 emplace_back()构造时,直接将值给对象的构造函数,通过定位new来实现构造。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值