我正在做一个项目,需要从数据文件中加载许多对象并将它们存储在内存中。因为有人告诉我堆栈空间很少,大量数据应该放在堆上,所以我把所有东西都放在堆上。然而,我的印象是我有点过头了。
我目前的设计是这样的:
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
。此外,RoadMap
调用者在添加节点时必须提供 unique_ptr
,这意味着他必须自己进行堆分配。
目前,与其他选项相比,我更倾向于选项 1。但是,我编写 C++ 代码的时间相对较短,不确定我是否完全理解内存管理背后的概念,这就是为什么我希望您(不)验证我的观点。我假设选项 1 是执行此操作的最佳方法是否正确?对于此类事情,您是否有其他最佳实践引用?
最佳答案
给 Node
一个移动构造函数和移动赋值运算符(以使集合上的操作便宜),然后混合使用选项 1 和 2。std::set
将已经在堆上分配其内容,因此您无需担心在堆上分配 RoadMap
。请注意 addNode
中的额外 std::move
以允许将 Node
移动到集合中。
class RoadMap
{
set<Node> allNodes;
void addNode (Node node)
{
allNodes.emplace(std::move(node));
}
};
int main()
{
RoadMap map;
// open file etc.
for (const auto& nodeData : nodesInFile)
{
map.addNode(Node(nodeData));
}
}
关于c++ - 将大对象放在堆上的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18329160/