0

所以我在使用指针和弄清楚如何有效地使用它们时遇到了一些麻烦。

假设我有一个案例,我在 while 循环中从堆栈中弹出“节点”对象,就像这样。

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

我想让它有效地运行我不应该在循环的每次迭代中创建一个新节点......所以我认为在循环外初始化一个节点指针可能更聪明:

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

但是,当我这样做时,obj 会被 pop 删除,因为它是一个引用......

创建副本并让指针指向副本会更有效,还是每次迭代只创建一个新节点。告诉我,如果我在这里的思考过程也偏离了基础,我现在只是想了解实现这一目标的有效方法。

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

4

2 回答 2

2

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

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

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

于 2013-04-11T03:18:15.730 回答
1

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

但是,如果您发现复制 s 的成本很高Node可能通过一些分析),您可以使用类似的东西,shared_ptr这样您就可以在复制 s 后获得所有权top(),随后pop()只会stack删除它对 that 的所有权Node如果您有证据表明副本是您的速度问题的根源,那么您只会初始化shared_ptr应该便宜得多的 s 。Node

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

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

于 2013-04-11T03:24:59.643 回答