我什么时候应该使用临时变量?

时间:2010-04-27 21:30:02

标签: c++ styles temporaries

具体来说,我想知道我应该写些:

{
    shared_ptr<GuiContextMenu> subMenu = items[j].subMenu.lock();
    if (subMenu)
        subMenu->setVisible(false);
}

或:

{
    if (items[j].subMenu.lock())
        items[j].subMenu.lock()->setVisible(false);
}

我不需要遵循任何风格指南。优化后,我认为这两种选择都不会对性能产生影响。什么是一般的首选风格,为什么?

编辑:项目类型[j] .subMenu是boost :: weak_ptr。 lock()从中创建一个shared_ptr。上面两个版本实际上有一个模糊的区别,关于临时shared_ptr持续多长时间,所以我将我的两个例子包装在{braces}中以解决那里的歧义。

10 个答案:

答案 0 :(得分:7)

另一种方法:

if(shared_ptr<GuiContextMenu> subMenu = items[j].subMenu.lock()) {
    subMenu->setVisible(false);
}
//subMenu is no longer in scope

我假设subMenuweak_ptr,在这种情况下,您的第二种方法会创建两个临时值,这可能是也可能不是问题。并且您的第一个方法将变量添加到比其需要更宽的范围。就个人而言,我尽量避免if语句中的作业,但这是少数几种我觉得它比其他选择更有用的案例之一。

答案 1 :(得分:4)

此特定情况中,您确实应该使用带有临时变量的版本。原因不是性能,而是正确性 - 基本上,您无法保证两个x.lock()调用返回相同的值(例如,如果另一个线程在两个调用之间释放对象的最后一个强引用)。通过在临时变量中保存强引用,可以确保它不会消失。

除此之外:

  • 编译器通常不能优化函数调用,除非它们可证明是无副作用(这很难做,但属性可能有帮助)或内联。在这种情况下,调用会产生副作用。

  • 使用临时文件可以使程序更短,更易读,更易于维护(例如,如果出现错误,可以将其固定在一个地方)

答案 2 :(得分:2)

我认为你对两种选择在优化后没有什么不同是正确的。

就个人而言,如果它使代码更具可读性,我会声明一个新变量,例如当你链接调用或将函数调用放在函数调用中时。只要它是可维护的并且代码在没有速度差异的情况下实现相同的效果,这一切都归结为可读代码。

修改

mmyers买了一个很好的评论。是的,请注意两次调用lock(),而不是一次。根据您的实施情况,它们会产生不同的效果。

答案 3 :(得分:1)

选择基本取决于您,但您应注意的基本事项是可维护性。

答案 4 :(得分:1)

在这个具体的例子中,我认为这取决于lock()的作用。功能昂贵吗?每次调用函数时它是否会返回不同的东西(第一次返回指针而第二次返回NULL)?是否有其他线程在两次调用lock()之间交错?

对于此示例,您需要了解lock()及其余代码的行为,以便做出明智的决定。

答案 5 :(得分:1)

当返回值是布尔值的任何其他值时,将其分配给中间变量通常可以简化调试。例如,如果您单步执行以下操作:

if( fn() > 0 ) ...

事实之后,您将知道该函数返回的值小于零,或者为零或更多。即使返回值不正确,代码仍可能正常工作。将它分配给可在调试器中检查的变量将允许您确定返回值是否是预期的。

当返回为布尔值时,实际值完全由代码流隐含,因此它不那么重要;但是在代码维护下你可能会发现以后需要这个结果,所以你可以决定在任何情况下都养成习惯。

即使返回值为布尔值,另一个需要考虑的问题是该函数是否具有所需的副作用,以及这是否可能受到短路评估的影响。例如在声明中:

if( isValid && fn() ) ...

永远不会调用该函数isValid是false。

在粗略的程序员维护下维护代码的情况(通常是经验不足的程序员来完成维护任务)很多,而且最好避免使用。

答案 6 :(得分:0)

我最喜欢第一个,因为它使代码更清晰易读,因此不易出错。例如,你忘记了第二个例子的括号:) 在这种情况下,实际上,我可能会在第二个示例中执行您所做的操作,但是如果我需要使用该子菜单多次,那么我将使用第一个子菜单以使代码更易于阅读。至于性能,我认为任何理智的编译器都能够优化它(这可能就是为什么你没有看到性能上的差异)。

另外,正如mmyers指出的那样,这也取决于lock()的作用。一般来说,如果它是一个简单的getter方法或类似的东西,你会没事的。

答案 7 :(得分:0)

无论你喜欢什么。对我来说,这取决于我将使用它多少;对于两行,我可能只是写出两次,而如果我更多地使用它,我会创建一个变量。但是,您最有可能必须维护此代码并继续查看它,因此请使用适合您的任何内容。当然,如果您所在的公司有编码指南,请遵循它。

答案 8 :(得分:0)

我认为首选的样式是您认为使代码更易读和可维护的任何样式。如果你是一个不止一个团队,唯一的另一个考虑因素是每个人采用相同的风格通常是一个好主意,同样为了可读性和易于维护。

答案 9 :(得分:0)

在这种情况下,我认为你应该使用临时的。即使您知道.lock()的实现很便宜,也可以改变。如果您不需要两次调用lock(),请不要。这里的值是它将您的代码与lock()的实现分离。这一般都是好事。