我正在做一个需要从数据文件中加载许多对象并将它们存储在内存中的项目。由于有人告诉我堆栈空间很少,并且应该在堆上存储大量数据,因此我将所有内容都放在堆上。但是,我的印象是我做得有点过头了。
我目前的设计是这样的:
class RoadMap
{
unique_ptr<set<unique_ptr<Node>>> allNodes;
void addNode(unique_ptr<Node> node)
{
this->allNodes->insert(std::move(node));
}
}
int main()
{
unique_ptr<RoadMap> map(new RoadMap());
// open file etc.
for (auto nodeData : nodesInFile)
{
map->addNode(unique_ptr<Node>(new Node(nodeData)));
}
}
根据我现在的理解,这会产生很多开销,因为涉及到许多我认为不需要的唯一指针。如果我理解正确,“指针链”中只有一个唯一的指针屏障就足够了。但是,我不确定执行此操作的最佳做法是什么。
选项1
class RoadMap
{
unique_ptr<set<Node>> allNodes;
void addNode (Node node)
{
this->allNodes->insert(node);
}
}
int main()
{
RoadMap map;
//open file etc.
for (auto nodeData : nodesInFile)
{
map.addNode(Node(nodeData));
}
}
在我看来,这样做的好处是RoadMap
类本身是唯一需要处理堆分配的类,并且在创建set
.
选项 2
class RoadMap
{
set<Node> allNodes;
void addNode (Node node)
{
this->allNodes.insert(node);
}
}
int main()
{
unique_ptr<RoadMap> map(new RoadMap());
// open file etc.
for (auto nodeData : nodesInFile)
{
map->addNode(Node(nodeData));
}
}
此处唯一指针仅在主函数中,这意味着RoadMap
该类的用户需要知道该对象可能会变得非常大并且应该放入堆栈中。我不认为这是一个非常好的解决方案。
选项 3
class RoadMap
{
set<unique_ptr<Node>> allNodes;
void addNode(unique_ptr<Node> node)
{
this->allNodes.insert(std::move(node));
{
}
int main()
{
RoadMap map;
// open file etc.
for (auto nodeData : nodesInFile)
{
map.addNode(unique_ptr<Node>(new Node(nodeData)));
}
}
此解决方案使用许多唯一指针,这意味着在删除RoadMap
许多析构函数delete
时需要调用 s。此外,RoadMap
调用者在添加节点时必须提供 a unique_ptr
,这意味着他必须自己进行堆分配。
现在,我更喜欢选项 1 而不是其他选项。但是,我只在相对较短的时间内编写 C++ 代码,并且不确定我是否完全理解内存管理背后的概念,这就是为什么我希望您(in)验证我的观点。假设选项 1 是最好的方法,我是否正确?您对此类事情的最佳实践有任何其他参考吗?