【C++学习笔记 21】C++中的动态数组 vertor
静态数组
首先来创建一个静态数组
#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++ 教程