文章目录
- 1 vector初始化方法
- 2 vector容器迭代器
- 3 data()函数
- 4 emplace_back()和push_back()的区别
- 5 insert()函数
- 6 vector删除元素
- 参考
1 vector初始化方法
方式1:
std::vector<double> values;//创建空的vcetor
values.reserve(20); //设置容器的内存分配,即至少可以容纳 20 个元素。
方式2:
std::vector<int> primes {2, 3, 5, 7, 11, 13, 17, 19};//创建一个含有 8 个素数的 vector 容器
方式3:
std::vector<double> values(20);//创建拥有20个元素的vector,他们的默认初始值是0
std::vector<double> values(20, 1.0);//创建拥有20个元素的vector,他们的默认值都是1.0
另外:圆括号 () 中的 2 个参数,既可以是常量,也可以用变量来表示,例如:
int num=20;
double value =1.0;
std::vector<double> values(num, value);
方式4:
通过存储元素类型相同的其它 vector 容器,也可以创建新的 vector 容器,例如:
std::vector<char>value1(5, 'c');
std::vector<char>value2(value1);
如果不想复制其它容器中所有的元素,可以用一对指针或者迭代器来指定初始值的范围,例如:
int array[]={1,2,3};
std::vector<int>values(array, array+2);//values 将保存{1,2}
std::vector<int>value1{1,2,3,4,5};
std::vector<int>value2(std::begin(value1),std::begin(value1)+3);//value2保存{1,2,3}
部分成员函数的用法:
#include <iostream>
#include <vector>
using namespace std;
int main()
{//初始化一个空vector容量vector<char>value;//向value容器中的尾部依次添加 S、T、L 字符value.push_back('S');value.push_back('T');value.push_back('L');//调用 size() 成员函数容器中的元素个数printf("元素个数为:%d\n", value.size());//使用迭代器遍历容器for (auto i = value.begin(); i < value.end(); i++) {cout << *i << " ";}cout << endl;//向容器开头插入字符value.insert(value.begin(), 'C');cout << "首个元素为:" << value.at(0) << endl;return 0;
}
输出结果为:
元素个数为:3
S T L
首个元素为:C
2 vector容器迭代器
以上在array中所讲的迭代器方法,在vector中同样适用,但是vector迭代器也有自己的独特之处:
1、因为vector可以初始化为空,所以不能使用迭代器对空的vector进行初始化。
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int>values;int val = 1;for (auto first = values.begin(); first < values.end(); ++first, val++) {*first = val;//初始化的同时输出值cout << *first;}return 0;
}
对于空的 vector 容器来说,begin() 和 end() 成员函数返回的迭代器是相等的,即它们指向的是同一个位置。
所以,对于空的 vector 容器来说,可以通过调用 push_back() 或者借助 resize() 成员函数实现初始化容器的目的。
2、vector 容器在申请更多内存的同时,容器中的所有元素可能会被复制或移动到新的内存地址,这会导致之前创建的迭代器失效
举个例子:
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int>values{1,2,3};cout << "values 容器首个元素的地址:" << values.data() << endl;auto first = values.begin();auto end = values.end();//增加 values 的容量values.reserve(20);cout << "values 容器首个元素的地址:" << values.data() << endl;while (first != end) {cout << *first;++first;}return 0;
}
运行程序,显示如下信息并崩溃:
values 容器首个元素的地址:0096DFE8
values 容器首个元素的地址:00965560
可以看到,values 容器在增加容量之后,首个元素的存储地址发生了改变,此时再使用先前创建的迭代器,显然是错误的。因此,为了保险起见,每当 vector 容器的容量发生变化时,我们都要对之前创建的迭代器重新初始化一遍:
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int>values{1,2,3};cout << "values 容器首个元素的地址:" << values.data() << endl;auto first = values.begin();auto end = values.end();//增加 values 的容量values.reserve(20);cout << "values 容器首个元素的地址:" << values.data() << endl;first = values.begin();//重新对迭代器进行初始化end = values.end();while (first != end) {cout << *first ;++first;}return 0;
}
运行结果为:
values 容器首个元素的地址:0164DBE8
values 容器首个元素的地址:01645560
123
3 data()函数
data()函数的功能是返回指向容器中首个元素的指针。通过该指针也可以访问甚至修改容器中的元素
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> values{1,2,3,4,5};//输出容器中第 3 个元素的值cout << *(values.data() + 2) << endl;//修改容器中第 2 个元素的值*(values.data() + 1) = 10;cout << *(values.data() + 1) << endl;return 0;
}
运行结果为:
3
10
4 emplace_back()和push_back()的区别
emplace_back() 和 push_back() 的区别,就在于底层实现的机制不同。push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。
#include <vector>
#include <iostream>
using namespace std;
class testDemo
{
public:testDemo(int num):num(num){std::cout << "调用构造函数" << endl;}testDemo(const testDemo& other) :num(other.num) {std::cout << "调用拷贝构造函数" << endl;}testDemo(testDemo&& other) :num(other.num) {std::cout << "调用移动构造函数" << endl;}
private:int num;
};
int main()
{cout << "emplace_back:" << endl;std::vector<testDemo> demo1;demo1.emplace_back(2); cout << "push_back:" << endl;std::vector<testDemo> demo2;demo2.push_back(2);
}
运行结果为:
emplace_back:
调用构造函数
push_back:
调用构造函数
调用移动构造函数
在此基础上,读者可尝试将 testDemo 类中的移动构造函数注释掉,再运行程序会发现,运行结果变为:
emplace_back:
调用构造函数
push_back:
调用构造函数
调用拷贝构造函数
由此可以看出,push_back() 在底层实现时,会优先选择调用移动构造函数,如果没有才会调用拷贝构造函数。
显然完成同样的操作,push_back() 的底层实现过程比 emplace_back() 更繁琐,换句话说,emplace_back() 的执行效率比 push_back() 高。因此,在实际使用时,建议优先选用 emplace_back()。
5 insert()函数
#include <iostream>
#include <vector>
#include <array>
using namespace std;
int main()
{std::vector<int> demo{1,2};//第一种格式用法demo.insert(demo.begin() + 1, 3);//{1,3,2}//第二种格式用法demo.insert(demo.end(), 2, 5);//{1,3,2,5,5}//第三种格式用法std::array<int,3>test{ 7,8,9 };demo.insert(demo.end(), test.begin(), test.end());//{1,3,2,5,5,7,8,9}//第四种格式用法demo.insert(demo.end(), { 10,11 });//{1,3,2,5,5,7,8,9,10,11}for (int i = 0; i < demo.size(); i++) {cout << demo[i] << " ";}return 0;
}
6 vector删除元素
参考
部分内容参考于C语言中文网;一个很不错的编程网站,建议大家多看看。