【C++之容器篇】精华:vector常见函数的接口的熟悉与使用

目录

    • 前言
    • 一、认识vector
      • 1. 介绍
      • 2. 成员类型
    • 二、默认成员函数(Member functions)
      • 1. 构造函数
      • 2. 拷贝构造函数
        • vector (const vector& x);
      • 3. 析构函数
      • 4. 赋值运算符重载函数
    • 三、迭代器(Iterators)
      • 1. 普通对象的迭代器
      • 2. const对象的迭代器
      • 3. 普通对象的反向迭代器
      • 4. const对象的反向迭代器
    • 四、容量接口(Capacity)
      • 1. size()
      • 2. capacity()
      • 3. reserve()
      • 4. resize()
    • 五、元素访问接口(Element access)
      • 1. operator[]
        • (1)reference operator[](size_t n)
        • (2)const reference operator[](size_t n)const
      • 2. at()
        • (1)reference at() const
        • (2)const reference at(size_t n) const
      • 3. front()
      • 4.back()
    • 六、修改接口(Modifiers)
      • 1. push_back()
      • 2. pop_back()
    • 七、vector常见题目

前言

前面我们在学习C语言版本的数据结构时,学习过SeqList顺序表的实现,C语言实现的顺序表存在一定的局限性,一次性只能支持存储一种类型的数据,今天我们将学习C++标准库中一种新的顺序表:vector的使用

一、认识vector

1. 介绍

vector是一个支持动态扩容的数组,并且是以模板进行支持的,所以可以实现存储不同类型的数据,实用性比较广。
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第1张图片

2. 成员类型

【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第2张图片

二、默认成员函数(Member functions)

1. 构造函数

【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第3张图片
标准库中的vector支持了很多版本的构造函数,但是在实际的使用过程中比较常用的是无参的构造函数。

  • 代码1:无参构造函数
int main()
{
	vector<int> v1;
	vector<double> v2;
	vector<string> v3;
	return 0;
}

调试结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第4张图片

  • 代码2:使用n个数据进行构造
int main()
{
	vector<int> v1(6, 8);
	vector<double> v2(5, 6.6);
	vector<string> v3(6, "hello std::vector");
	return 0;
}

调试结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第5张图片

  • 代码3:使用一个迭代器区间进行构造
int main()
{
	string s("hello std::vector::vector(iterator begin,iterator end)");
	vector<char> v(s.begin(), s.end());

	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第6张图片

2. 拷贝构造函数

vector (const vector& x);

vector的拷贝构造函数需要实现成深拷贝,其用法和其他类基本类似

  • 代码:
int main()
{
	string s("hello std::vector::vector(iterator begin,iterator end)");
	vector<char> v(s.begin(), s.end());
	vector<char> v1(v);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;

	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第7张图片

3. 析构函数

vector中有动态申请的资源,所以需要手动实现析构函数在函数生命周期结束时自动调用该析构函数完成资源的释放。

4. 赋值运算符重载函数

【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第8张图片

赋值运算符重载函数需要实现的也是深拷贝,下面介绍其用法:

  • 代码:
int main()
{
	string s("hello std::vector(const vector&v)");
	vector<char> v1(s.begin(),s.end());
	vector<char> v2;
	v2 = v1;
	cout << "v1:" << endl;
	for (auto ch : v1)
	{
		cout << ch << " ";
	}
	cout << endl;

	cout << "v2:" << endl;
	for (auto ch : v2)
	{
		cout << ch << " ";
	}
	cout << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第9张图片

三、迭代器(Iterators)

1. 普通对象的迭代器

普通对象一般调用的就是普通的迭代器,迭代器的一个很重要的作用就是遍历数组,同时范围for的底层原理就是迭代器

  • 代码1:遍历
int main()
{
	string s("hello std::vector::iterator begin() and end()");
	vector<char> v(s.begin(), s.end());

	vector<char>::iterator vit = v.begin();
	while (vit != v.end())
	{
		cout << *vit << " ";
		vit++;
	}
	cout << endl;

	for (auto& ch : v)
	{
		cout << ch << " ";
	}
	cout << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第10张图片

  • 代码2:支持修改
int main()
{
	string s("hello std::vector::iterator begin() and end()");
	vector<char> v(s.begin(), s.end());

	vector<char>::iterator vit = v.begin();
	while (vit != v.end())
	{
		(*vit) += 1;
		cout << *vit << " ";
		vit++;
	}
	cout << endl;

	for (auto& ch : v)
	{
		cout << ch << " ";
	}
	cout << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第11张图片

2. const对象的迭代器

const类型的对象调用const版本的迭代器,不支持修改,支持遍历容器

  • 代码:
int main()
{
	string s("hello std::vector::const_iterator begin() and end()");
	const vector<char> v(s.begin(), s.end());

	vector<char>::const_iterator vit = v.begin();
	while (vit != v.end())
	{
		cout << *vit << " ";
		vit++;
	}
	cout << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第12张图片

  • 代码2:不支持修改
    【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第13张图片

3. 普通对象的反向迭代器

  • 代码:
int main()
{
	string s("hello std::vector::iterator rbegin() and rend()");
	vector<char> v(s.begin(), s.end());

	vector<char>::reverse_iterator vit = v.rbegin();
	while (vit != v.rend())
	{
		cout << *vit << " ";
		vit++;
	}
	cout << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第14张图片

4. const对象的反向迭代器

  • 代码:
int main()
{
	string s("hello std::vector::const_reverse_iiterator rbegin() and rend()");
	const vector<char> v(s.begin(), s.end());
	vector<char>::const_reverse_iterator vit = v.rbegin();
	while (vit != v.rend())
	{
		cout << *vit << " ";
		vit++;
	}
	cout << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第15张图片

四、容量接口(Capacity)

1. size()

【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第16张图片

  • 代码:
int main()
{
	string s("hello std::vector::size()");
	vector<char> v(s.begin(),s.end());

	cout << "size:" << v.size() << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第17张图片

2. capacity()

【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第18张图片

  • 代码:
int main()
{
	string s("hello std::vector::capacity()");
	vector<char> v(s.begin(), s.end());

	cout << "capacity:" << v.capacity() << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第19张图片

3. reserve()

【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第20张图片

  • 代码:
int main()
{
	string s("hello std::vector::reserve()");
	vector<char> v(s.begin(), s.end());

	cout << "capacity:" << v.capacity() << endl;
	v.reserve(100);
	cout << "capacity:" << v.capacity() << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第21张图片

4. resize()

【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第22张图片

  • 代码1:
int main()
{
	string s("hello std::vector::resize()");
	vector<char> v(s.begin(),s.end());

	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;

	v.resize(100, 'x');
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第23张图片

  • 代码2:
int main()
{
	string s("hello std::vector::resize()");
	vector<char> v(s.begin(), s.end());
	v.reserve(50);
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;

	v.resize(46, 'x');
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第24张图片

  • 代码3:
int main()
{
	string s("hello std::vector::resize()");
	vector<char> v(s.begin(), s.end());
	v.reserve(50);
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;

	v.resize(23, 'x');
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第25张图片

五、元素访问接口(Element access)

1. operator[]

在这里插入图片描述

(1)reference operator[](size_t n)

  • 代码:
int main()
{
	string s("hello std::vector::reference operator[](size_t n)");
	vector<char> v(s.begin(), s.end());

	for (size_t i = 0; i < v.size(); i++)
	{
		cout << v[i] << " ";
	}
	cout << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第26张图片

(2)const reference operator[](size_t n)const

  • 代码:
int main()
{
	string s("hello std::vector::const reference operator[](size_t n)");
	const vector<char> v(s.begin(), s.end());

	for (size_t i = 0; i < v.size(); i++)
	{
		cout << v[i] << " ";
	}
	cout << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第27张图片

2. at()

【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第28张图片

(1)reference at() const

  • 代码:
int main()
{
	string s("hello std::vector::reference at(size_t n)");
	vector<char> v(s.begin(), s.end());

	for (size_t i = 0; i < v.size(); i++)
	{
		cout << v.at(i) << " ";
	}
	cout << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第29张图片

(2)const reference at(size_t n) const

  • 代码:
int main()
{
	string s("hello std::vector::const reference at(size_t n) const");
	const vector<char> v(s.begin(), s.end());

	for (size_t i = 0; i < v.size(); i++)
	{
		cout << v.at(i) << " ";
	}
	cout << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第30张图片

3. front()

【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第31张图片

  • 代码:

int main()
{
	string s("hello std::vector::front()");
	vector<char> v(s.begin(), s.end());

	cout << v.front() << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第32张图片

4.back()

【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第33张图片

  • 代码:
int main()
{
	string s("hello std::vector::back()");
	vector<char> v(s.begin(), s.end());

	cout << v.back() << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第34张图片

六、修改接口(Modifiers)

1. push_back()

【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第35张图片

  • 代码:
int main()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);

	vector<int>::iterator vit = v.begin();
	while (vit != v.end())
	{
		cout << *vit << " ";
		vit++;
	}
	cout << endl;

	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第36张图片

2. pop_back()

【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第37张图片

  • 代码:
int main()
{

	string s("hello std::vector pop_back()");
	vector<char> v(s.begin(), s.end());
	vector<char>::iterator vit = v.begin();
	while (vit != v.end())
	{
		cout << *vit << " ";
		vit++;
	}
	cout << endl;

	v.pop_back();
	v.pop_back();

	for (auto& ch : v)
	{
		cout << ch << " ";
	}
	cout << endl;
	return 0;
}

运行结果:
【C++之容器篇】精华:vector常见函数的接口的熟悉与使用_第38张图片

七、vector常见题目

  1. 下面关于迭代器失效的描述哪个是错误的( )

A.vector的插入操作一定会导致迭代器失效
B.vector的插入操作有可能不会导致迭代器失效
C.vector的删除操作只会导致指向被删除元素及后面的迭代器失效
D.vector的删除操作只会导致指向被删除元素的迭代器失效

分析:
A.vector的插入操作如果导致底层空间重新开辟,则迭代器就会失效。如果空间足够,那么迭代也算失效了,因为数据相对位置已经发生改变,他已经不是指向之前的位置了。

B.参考A的解释。

C.vector删除,当前元素肯定失效,后面元素会牵扯到移动数据,因此删除元素后面的迭代器也会失效

D. vector的删除操作不光会导致指向被删除元素的迭代器失效,删除元素后面的迭代器也会失效

你可能感兴趣的:(STL,c++,vector,STL)