vector的初始化,相信会写c++的人都很熟悉,c++11对此也改进了很多,更方便。
以下是使用vector初始化的几个例子:
- 从数组初始化vector:
int arr[] = {1, 2, 3, 4, 5};
vector<int> vec(arr, arr + sizeof(arr) / sizeof(int));
- 使用默认值初始化vector:
vector<int> vec(5, 0); // 创建一个大小为5,值为0的vector
- 使用另一个vector初始化vector:
vector<int> vec1 = {1, 2, 3, 4, 5};
vector<int> vec2(vec1); // 使用vec1初始化vec2
- 使用迭代器初始化vector:
vector<int> vec(arr, arr + sizeof(arr) / sizeof(int));
vector<int> vec2(vec.begin() + 1, vec.end() - 1); // 使用vec中的第2个到倒数第2个元素初始化vec2
- 使用列表初始化的方式:
vector<int> vec = {1, 2, 3, 4, 5};
=========分割线==================分割线==================
那么,我下面提出的问题,就比较细节了,请观察下面两段代码,有什么区别:
//代码1
std::vector<std::vector<CAMFeature>*> vpvCams(8, new std::vector<CAMFeature>());
//代码2
std::vector<std::vector<CAMFeature>*> vpvCams(8, nullptr);
for (size_t i = 0; i < vpvCams.size(); ++i)
{
vpvCams[i] = new std::vector<CAMFeature>();
}
这里,我们在vector的内部定义了一个指针,其实指针的类型无所谓,我这里为了方便直接复制粘贴过来了。
那么,想问一下,这两段代码的效果是一样的吗?先不看答案,思考一下呗。
=========分割线==================分割线==================
为了防止你一下子就看到答案,这里先举一个类似的例子占用一点空间,并且这个例子更具体,更有说服性,下面也将用这个例子来解释说明:
#include <vector>
#include <iostream>
using namespace std;
int main()
{
//代码1
std::vector<int*> vPInt(8, new int());
//代码2
std::vector<int*> vPInt2(8, nullptr);
for (size_t i = 0; i < vPInt2.size(); ++i)
{
vPInt2[i] = new int();
}
for (int i = 0; i < 8; ++i)
{
cout << &(*vPInt[i]) << std::endl;
}
cout << "\n";
for (int i = 0; i < 8; ++i)
{
cout << &(*vPInt2[i]) << std::endl;
}
return 0;
}
代码1和代码2,同样初始化了一个vector,但是他们初始化的方法有区别,现在的问题是,他们的效果相同吗?
我们分别输出了两种初始化方式下,输出容器中的结果,因为指针如果直接使用cout输出会输出指针对应的结果,所以我们取了一次地址。
先公布一下答案:不同!
从结果中可以看到,两种初始化方式的结果是不同的,第一种初始化方式,vecor容器中存储的指针是相同的,也就是说,new vector这句话实际上只执行了一次,然后拷贝到各个容器,而第二种初始化方式才是我们需要的,分别对每一个指针进行初始化。
这说明,不应当在vecor初始化的时候,对指针进行new,因为那个结果不是我们想要的!!
而如果是其他正常的类型,不是指针的话,那上面两种初始化的结果相同:
//方法1
vector<int> vec(5, 10); // 创建一个大小为5,值为10的vector
//方法2
vector<int> vec(5); // 创建一个大小为5
for (int i = 0; i < 5; ++i)
{
vec[i] = 10;
}
虽然写c++很多年了,一直没有注意到这个细节,说来惭愧,不过最近在做项目的过程中发现了这个问题,特此纪念一下。
欢迎交流与讨论。