本文为学习C++的阅读、学习笔记,如有错漏请联系作者。

 

1. 基本概念

    vector是一个类模板,在C++中使用模板可以编写一个类定义或函数定义,而用于多种不同的数据类型。vector是同一种类型的对象的集合,由于可以包含其他对象的特性,所以也将vector称为容器。

2. 使用方法

    要使用vector类模板,需要添加头文件,并使用using声明:

#include <vector>

using  std::vector;

    关于使用using声明,避免在头文件中进行using声明,以免存在多个文件中都进行了using声明导致重定义等错误。

2.1 定义和初始化

    将类型放在类模板(vector)后的尖括号来指定类型,如下面这个声明表示ivec是保存的是一个int类型的对象:

vector<int> ivec;

    vector对象的初始化方法:

    其中,尖括号的T表示类模板vector所支持的数据类型。在C语言初始化的时候,一般会预先分配合适的空间,但是在C++中,通常是先初始化一个空vector对象,然后再动态地增加元素。

    初始化时,如果没有指定元素的初始化式,则标准库将会自行提供一个元素初始值进行初始化。

    使用vector<T> v5{1,2,3,4}这种初始化方法,将一个序列放入vector中。

2.2 vector对象的操作

    增删查改是最基本的数据操作,书中提到了以下几种vector操作的函数:

    其中,push_back(t)是在vector对象末尾添加一个元素t;size()是获得vector对象的个数。

    访问一个vector对象可以使用for循环和迭代器进行遍历,也可以使用下标的形式进行访问:

    vector<int> num1{1,2,1,2};

    //使用迭代器访问
    for (vector<int>::iterator iter = num1.begin(); iter != num1.end(); iter++) {
        cout << *iter << endl;
    }

    //下标访问
    for (int i = 0; i < num1.size(); i++) {
        cout << num1[i] << endl;
    }

    C++还提供了一种叫做范围for循环的for语句,可以用作遍历vector对象:

vector<int> test{1,2,3,4,5,6};

for (auto &i : test) {
    cout << i << " ";
}

    以上是遍历vector对象的方式,查找了其他的资料,找到了删除操作的几个函数,参考博文:vector删除元素之pop_back(),erase(),remove()。使用pop_back()可以删除vector对象的最后一个元素,而采用remove()一般情况下不会改变容器的大小,而pop_back()与erase()等成员函数会改变容器的大小。

2.3 示例

示例说明:初始化vector对象,紧接着使用范围for循环对vector对象进行遍历;使用push_back函数和pop_back函数进行增加对象和删除对象,vector对象也可以使用下标进行访问或操作。如果不了解范围for循环的,可以参考博文:C++11新特性之基本范围的For循环(range-based-for)

#include <iostream>
#include <vector>


int main() {
	//initial the test_vector: there are 15 integer, and initial value is 10.
	std::vector<int> test_vector(15, 10);

	std::cout << "its size is :"<< test_vector.size() << std::endl;
	//traverse the test_vector 
	for (std::vector<int>::iterator itr = test_vector.begin(); itr != test_vector.end(); itr++) {
		std::cout << *itr << " ";
	}

	//add
	test_vector.push_back(20);
	std::cout << "\nits size is :" << test_vector.size() << std::endl;

	//use subscript to operation
	std::cout << "the last value is :" << test_vector[test_vector.size()-1] << std::endl;

	//delete
	test_vector.pop_back();
	std::cout << "its size is :" << test_vector.size() << std::endl;
	std::cout << "the last value is :" << test_vector[test_vector.size() - 1] << std::endl;

	return 0;

}

示例效果:

its size is :15
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10

its size is :16
the last value is :20
its size is :15
the last value is :10

2.5 vector嵌套vector对象

    上面是简单使用vector的方法,后来用到了一些稍微复杂一点的用法,就是vector的嵌套,这里补充添加上来。(2020/08/26)

    vector是一个模板,能够容纳接大多数类型的对象作为其元素,甚至组成vector的元素也可以是vector。早期版本的C++标准中,如果声明vector的元素为vector类型时,应该在vector对象的末尾添加一个空格,写成:vector<vector<int> >;而在C++11新标准则不需要添加这个空格。

    这里以vector<vector<int>>这个声明为例,我们可以把它与二维数组进行类比,下面通过下标访问的方式访问vector对象:

vector<int> test;
vector<vector<int>> test2{ { 1,2,3,4,5,6,7 },{ 1,2,3,4,5,6 }};

for (int i = 0; i <test2.size(); i++) {
    test = test2[i];
    for (int j = 0; j < test.size(); j++) {
        cout << test2[i][j] << " ";
    }
    cout << "\n";
}

输出结果:

1 2 3 4 5 6 7
1 2 3 4 5 6

    这样我们就可以使用类似二维数组的方式对vector嵌套vector对象的变量进行操作了。

2.6 vector的拷贝

假设声明了test变量,要实现对test变量的拷贝:

vector<int> test{1,2,3,4};

有下面几种方法:

(1)声明新变量时,初始化拷贝

这种声明方法不会改变原来变量中的数据:

vector<int> tmp(test);

(2)利用vector的assign函数

复制了一份数据,test中的数据也是不变:

vector<int> tmp;
tmp.assign(test.begin(), test.end());

(3)利用vector的swap函数

将test中数据全部移到temlist中,此时test中为空了

vector<int> tmp;
tmp.swap(test);

(4)利用vector的insert函数

这种拷贝方式是在原有的数据的尾部插入目标数据,相当于复制了一份数据:

tmp.insert(tmp.end(), test.begin(), test.end());

2.7 存储自定义数据类型

自定义结构体, 重载 ==操作符:

typedef struct _Point
{
    int x;
    int y;

    _Point(int _x, int _y)
    {
        x = _x;
        y = _y;
    }

    bool operate ==(const int _x, const int _y)const
    {
        return ((x == _x)&&(y == _y));
    }
}Point;

添加和访问都通过迭代器:

std::vector<Point> test;
auto it = find(test.begin(), test.end(), tmp);
if(it != test.end())
{
    (*it).x = 10;
    (*it).y = 10;
}

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐