我有一个Mesh
类,我想拥有vertices
、indices
、vertex_normals
等几个不同的“类似数组”结构的所有权。
我希望Mesh
类完全独立于这些格式的源代码,因为我需要支持许多3d格式,因此我目前有一组加载器函数,可以从特定格式读取3d数据,创建网格,并将其分配给Model
的示例(包含unique_ptr
到特定Mesh
)。
我目前的做法是在loader函数中简单地堆分配数组,然后将指向这些数组的指针传递给Mesh
构造函数。但看起来使用std::vector
或std::unique_ptr
会更安全。一个loader函数(特别是从OBJ文件加载的函数)的快速模型如下所示:
void load_OBJ(std::shared_ptr<Model> model, std::string file_path){
# Read the 3d data
...
# Create the Mesh object
std::unique_ptr<Mesh> mesh(new Mesh());
# Add the 3d data to the Mesh (???)
mesh->set_vertices( ??? );
mesh->set_indices( ??? );
...
# Assign the Mesh object to the Model:
model->set_mesh(mesh);
};
我的第一个直觉React是,因为Mesh
将保持对其所有成员的独占所有权,所以我应该使用std::unique_ptr
,所以类似于以下内容:
class Mesh {
public:
std::unique_ptr<Vector3[]> vertices;
uint32_t num_vertices;
Mesh() { };
~Mesh() { };
void set_vertices(std::unique_ptr<Vector3[]>& new_vertices, uint32_t num_vertices){
this->vertices = std::move(new_vertices);
this->num_vertices = num_vertices;
};
但后来我开始怀疑std::vector
是否是更好的方法。在这种情况下,能够从Mesh
访问数据的速度将是极其重要的。(使用编译器优化)提示我,从std::unique_ptr<Vector3[]>
和std::vector<Vector3>
访问数据实际上是无法区分的。我不知道这里是否还有什么我遗漏的东西需要考虑?
1条答案
按热度按时间pbpqsu0x1#
std::vector
为您提供了对动态大小的元素数组的独占所有权,这正是您想要做的。它还通过允许您保存容易出错的显式大小变量来简化事情。使用向量也不会引入太多开销:它只是一个指向某个内存的指针,加上了
size
和capacity
(实际上,它们也被实现为指针,所以一个向量就是三个指针)。如果你要把
push_back
导入到vector中,请确保先用合适的大小调用reserve
:否则,向量的默认增长策略可能会使其大于您所需要的大小,从而浪费内存(如果我没记错的话,每当分配给向量的存储空间变满时,向量的大小默认会翻倍)。
如果你想把
memcpy
转换成向量,你必须先给resize
它分配一个适当的存储量。要传递向量而不进行复制,请使用
std::move
。它可以归结为与unique_ptr
相同的操作--只是移动几个指针。您可以在需要时轻松复制向量,但不是必须这样做。如果你想让一个函数或构造函数“消费”一个向量(取得它的所有权),只需要按值取它,然后把它移到它的最终目的地:
如果你用一个临时对象(或移动对象)调用函数,则不会在那里进行复制;但是如果你用左值调用它,它会进行复制并保持原始对象不变,这意味着你可以选择是复制还是移动对象到函数中。