c++中vector初始化的一个有趣的细节问题

vector的初始化,相信会写c++的人都很熟悉,c++11对此也改进了很多,更方便。

以下是使用vector初始化的几个例子:

  1. 从数组初始化vector:
int arr[] = {1, 2, 3, 4, 5};
vector<int> vec(arr, arr + sizeof(arr) / sizeof(int));
  1. 使用默认值初始化vector:
vector<int> vec(5, 0); // 创建一个大小为5,值为0的vector
  1. 使用另一个vector初始化vector:
vector<int> vec1 = {1, 2, 3, 4, 5};
vector<int> vec2(vec1); // 使用vec1初始化vec2
  1. 使用迭代器初始化vector:
vector<int> vec(arr, arr + sizeof(arr) / sizeof(int));
vector<int> vec2(vec.begin() + 1, vec.end() - 1); // 使用vec中的第2个到倒数第2个元素初始化vec2
  1. 使用列表初始化的方式:
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 << "
";

	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++很多年了,一直没有注意到这个细节,说来惭愧,不过最近在做项目的过程中发现了这个问题,特此纪念一下。

欢迎交流与讨论。

经验分享 程序员 微信小程序 职场和发展