赞
踩
方式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
以上在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
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
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()。
#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; }
部分内容参考于C语言中文网;一个很不错的编程网站,建议大家多看看。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。