【C++学习笔记 21】C++中的动态数组 vertor

时间:2024-10-02 20:28:01

静态数组

首先来创建一个静态数组

#include <iostream>
#include <string>

struct Vertex
{
	float x, y, z;
};

std::ostream& operator<<(std::ostream& stream, const Vertex& vertex)
{
	stream << vertex.x << "," << vertex.y << "," << vertex.z;
	return stream;
}

int main()
{
	Vertex* vertices = new Vertex[5];

	std::cin.get();
}

如此创建的数组为静态的,其特点是数组的长度已知,其本质是一串连续的内存空间,无法随意的修改它的大小。

动态数组(vector)

现在将代码改为使用动态数组

#include <iostream>
#include <string>
#include <vector>

struct Vertex
{
	float x, y, z;
};

std::ostream& operator<<(std::ostream& stream, const Vertex& vertex)
{
	stream << vertex.x << "," << vertex.y << "," << vertex.z;
	return stream;
}

int main()
{
	std::vector<Vertex> vertices;
	vertices.push_back({ 1, 2, 3 });
	vertices.push_back({ 4, 5, 6 });

	for (Vertex& v : vertices)
	{
		std::cout << v << std::endl;
	}

	std::cin.get();

动态数组可以方便的向其中添加内容,这里可以使用其提供的push_back方法添加内容。
或是使用vertices.erase(vertices.begin() + 1),去删除其中的第二个元素,这样进行索引的原因是其需要接受一个迭代器。

对代码进行优化

标准向量类的工作方式是创建一个向量,然后向后添加元素,如果向量的内存空间不够了,那它将进行的操作是:分配一块新的足够大的内存,将旧的内容以及要添加的新元素写入新内存,再删除旧的内存。重新分配内存的过程往往运行缓慢。因此如果能够避免复制的操作,将加快运行速度。
先增加一段构造函数,当向量被复制时会在终端中打印出提示。

#include <iostream>
#include <string>
#include <vector>

struct Vertex
{
	float x, y, z;

	Vertex(float x, float y, float z)
		:x(x), y(y), z(z)
	{
	}

	Vertex(const Vertex& vertex)
		:x(vertex.x), y(vertex.y), z(vertex.z)
	{
		std::cout << "Copied!" << std::endl;
	}
};

std::ostream& operator<<(std::ostream& stream, const Vertex& vertex)
{
	stream << vertex.x << "," << vertex.y << "," << vertex.z;
	return stream;
}

int main()
{
	std::vector<Vertex> vertices;
	vertices.push_back(Vertex(1, 2, 3));
        vertices.push_back(Vertex(4, 5, 6));
        vertices.push_back(Vertex(7, 8, 9));

	std::cin.get();
}

当运行这段代码时,提示一共进行了六次复制操作。
第一,在第一次向向量中添加时就发生了一次复制,这是因为Vertex变量实际是在main函数中创建的,因此将其添加进向量需要经历一次复制,这是一处可以优化的地方。
第二,向量的默认初始容量为1,当再次向后添加时,会发生复制,这是第二处可优化的地方。
如果知道项目所需时,第二处可以轻松优化,代码如下

int main()
{
	std::vector<Vertex> vertices;
	vertices.reserve(3);
	vertices.push_back(Vertex(1, 2, 3));
	vertices.push_back(Vertex(4, 5, 6));
	vertices.push_back(Vertex(7, 8, 9));

	std::cin.get();
}

此时运行,提示一共进行三次复制操作。
第一处可优化的地方是直接在向量中构造,而不是现在主函数构造,再进行复制,可以使用如下方法:

int main()
{
	std::vector<Vertex> vertices;
	vertices.reserve(3);
	vertices.emplace_back(1, 2, 3);
	vertices.emplace_back(4, 5, 6);
	vertices.emplace_back(7, 8, 9);

	std::cin.get();
}

使用这个方法,传入的不再是一个Vertex对象,而是构造所需的参数列表。


教程来源:The Cherno C++ 教程