具有持久位置的 C++ 动态数据类型
Posted
技术标签:
【中文标题】具有持久位置的 C++ 动态数据类型【英文标题】:C++ dynamic datatype with persistent location 【发布时间】:2015-07-25 15:42:00 【问题描述】:这个问题听起来有点可笑,但也许是可能的。
首先一些信息: 我正在为体素地形引擎创建一个块管理系统。 每个块必须能够访问其 6 个相邻块中的每一个。所以每个块都包含一个指向他的 6 个邻居的指针。这就是为什么一个块的内存位置不能改变的原因。目前我的设置如下所示:
ChunkMap chunks; // unordered_map of chunks
ChunkSet createdChunks; // set of pointers to unordered_map entries
ChunkSet generatedChunks; // set of pointers to unordered_map entries
vector<Chunk*> renderedChunks;
由于 unordered_map 会更改其条目的位置,这会导致错误,因为指向块邻居的指针正在访问错误的位置。
总结: 数据类型应该
拥有永久内存地址 支持添加和删除未知数量的条目 尽可能高效提前致谢!
【问题讨论】:
我很惊讶,你甚至考虑使用std::
容器来完成这样的任务。您需要一个专门的、面向性能的数据结构。 std::
中没有任何内容可用于此类任务。即使是这样,您仍然可以通过定制、精心设计、精心实施的解决方案获得更好的性能。但这只是我的看法(*)。 (*) 我目前正在研究多平台渲染引擎,所以这是我当前的主题。这也是我认为你不应该这样做的原因。
“尽可能高效”实际上取决于您打算如何使用它。例如,您是否需要随机访问或按键查找,或者从头到尾的迭代是否足够?但在不知不觉中,我会说std::list
是一个不错的起点,因为它不应该在操作列表的其他部分时更改其元素的内存位置。
" 每个块必须能够访问其 6 个相邻块中的每一个。"恕我直言,我认为你应该尝试改变这一点,这感觉对一个班级来说责任太大了。
*Mateusz 可能是个好主意,我只是在 c++ 方面还没有那么丰富。 *TheUndeadFish 如果这是正确的,列表可能是解决方案;我会尝试一下! *Daniel 每次块更改时,我的块都需要有关其邻居的信息,因为立方体面彼此相邻
【参考方案1】:
具有持久内存位置和动态大小不会同时发生在同一类型(至少不是任何std::
容器)。
你的三个主要选择:
-
从一开始就限制元素的数量(可能是很大的数量)
在存储中存储指向对象而不是对象的指针 [这样,即使存储指针的位置发生变化,对象本身也具有固定的分配地址]。
创建您自己的容器来分配存储“块”[一些合理的,最好是固定大小的],例如链接列表或块向量,并存储数据。如果大小足够大 [几千个元素],那么开销将是最小的。
任何容器的效率实际上取决于您正在执行的操作 - 在std::vector
中插入和删除效率不高,但遍历所有元素是有效的。插入和删除在std::list
中很好,但是从一个元素走到另一个元素涉及到指针追逐,这对效率不是很好。 std::map
非常适合基于某个键进行查找,插入/删除相对高效,但遍历所有内容类似于std::list
。 std::unordered_map
有点像用于插入的std::vector
[当它变得太大时,它会重新分配整个表],但查找特定元素的速度非常快。
【讨论】:
谢谢!存储指向对象的指针通常是我打算做的。所以选择2对我来说听起来最好。你是什么意思?当我有一个指向对象的指针时,我仍然必须将它存储在某个地方!?我已经尝试将它们存储在向量中,并且我的 unordered_map 包含指向它们的指针,但它也给了我一个“SIGTRAP”调试器错误。 是的,但是如果你为它分配了一次空间,它就不会移动,所以你可以使用std::vector
、std::map
或其他任何东西来存储指针,因为它们是将是相同的值,无论它们存储在容器中的何处 -> 你不在乎是否再次分配。
显然,如果您错误地使用了指针,那就是另一回事了——这不是您的问题要问的问题。以上是关于具有持久位置的 C++ 动态数据类型的主要内容,如果未能解决你的问题,请参考以下文章