为指针赋值副本

Assign copies to pointers

本文关键字:副本 赋值 指针      更新时间:2023-10-16

所以我在使用指针时遇到了一点麻烦,不知道如何有效地使用它们。

假设我有一个例子,我在while循环中从堆栈中弹出"Node"对象,就像这样。

while(...) {
   Node obj = stack.top();
   stack.pop();
   //do something with the obj
}

我想让它有效地运行,我不应该在循环的每次迭代中创建一个新的节点…因此,我认为在循环之外初始化Node指针可能更明智:

Node* obj;
while(...) {
   obj = &stack.top();
   stack.pop();
   //do something with the obj
}

然而,当我这样做的对象被删除与pop,因为它是一个引用…

是创建一个副本并让指针指向副本更有效,还是每次迭代只创建一个新的Node更有效?告诉我,如果我的思维过程也偏离了基础,我只是想学习有效的方法来完成这件事。

编辑:这是我测试Dijkstra算法的一部分,我正在搜索许多节点,它运行缓慢,所以我试图尽可能减少运行时间。

复制和创建指向副本的指针与第一个示例大致相同。修复第二个示例:

Node* obj;
while(...) {
    obj = &stack.top();
    // do something with the obj
    stack.pop(); // do this after processing
}

而且,大多数人会认为这是一个微优化。除非您的Node类非常庞大,并且您已经将这个特定的代码片段确定为瓶颈,否则您最好不要担心它。

这实际上取决于复制Node的成本。在您的第一个示例中,您已经制作了top()的副本。通常这样做就足够了。

然而,如果你发现它昂贵的复制Node s(也许通过一些分析),你可以使用像shared_ptr这样的东西,这样你可以获得所有权一旦你做top(),和随后的pop()只使stack删除它的所有权Node。那么你将只初始化shared_ptr s,这应该相当便宜,如果你有证据表明Node副本是你的速度问题的根源。

如果Node已经分配了成员数据,并且你有一个复制构造函数来复制这个分配的数据,另一件要考虑的事情是,你可以创建一个函数,而不是复制数据,你只是窃取指向该数据的指针,考虑到你将在之后删除Node。在这种情况下,复制已分配的内存是没有意义的。

首先通过一个分析器来运行它可能更有意义,以确定是什么导致了你的程序变慢,它可能只是一个自然的变慢,随着输入大小的缩放,由于算法实现本身的限制。如果您不确定这就是慢速的根源,那么可能不值得为优化应用程序的这一特定方面而付出努力和麻烦。