题
具体来说,我想知道我应该写的哪一个:
{
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 :: feek_ptr。 lock()从中创建一个共享_ptr。上面的两个版本实际上存在歧义差异,即临时共享_ptr持续多长时间,因此我将两个示例包裹在{braces}中以解决那里的歧义。
解决方案
另一种方法:
if(shared_ptr<GuiContextMenu> subMenu = items[j].subMenu.lock()) {
subMenu->setVisible(false);
}
//subMenu is no longer in scope
我假设 subMenu
是一个 weak_ptr
, ,在这种情况下,您的第二种方法会创建两个临时性,这可能不是一个问题。并且您的第一个方法为更大的范围添加了一个变量。就个人而言,我尝试避免在 if
陈述,但这是我觉得它比其他替代方案更有用的少数情况之一。
其他提示
在 这种特殊情况, , 你 真的应该 使用带有临时变量的版本。原因不是性能,而是正确性 - 基本上,您不能保证这两个 x.lock()
呼叫返回相同的值(例如,如果另一个线程仅在两个调用之间释放对象上的最后一个强引用)。通过在临时变量中保留强有力的参考,您可以确保它不会消失。
除此之外:
编译器通常无法优化函数呼叫,除非它们证明是无副作用的(这很难做到,但属性可能会有所帮助)或嵌入式。在这种情况下,呼叫具有副作用。
使用临时性可能会导致更短,更可读性和更可维护的程序(例如,如果出现错误,您可以将其修复到一个地方)
我认为您对两种选择在优化后都没有什么不同。
就个人而言,如果新变量使代码更可读取,例如当您链接呼叫或将函数调用在函数呼叫中。只要它可以维护并且代码在无速度差异下实现相同的效果,所有这些都可以归结为可读的代码。
编辑:
米尔斯(Mmyers)发表了很好的评论。是的,请小心打电话 lock()
两次,而不是一次。根据您的实施,它们将产生不同的影响。
选择本质上取决于您,但是您应该注意的基本内容是可维护性。
当返回值是布尔值的其他任何东西时,将其分配给中间变量通常可以简化调试。例如,如果您介绍以下内容:
if( fn() > 0 ) ...
事实之后,您将知道的只是该函数返回的值小于零或零或更多。即使返回值不正确,代码仍然可能工作。将其分配给可以在调试器中检查的变量,将允许您确定是否预期返回值。
当返回是布尔值时,实际值完全由代码流隐含,因此它不太关键。但是,在代码维护下,您可能会稍后发现您需要该结果,因此无论如何,您都可以决定将其养成习惯。
即使在返回值为布尔值的地方,要考虑的另一个问题是该函数是否需要副作用,以及这是否可能受到短路评估的影响。例如在语句中:
if( isValid && fn() ) ...
该函数永远不会称为Isvalid是错误的。
粗心的程序员在维护下可能会破坏代码的情况(通常是经验较低的程序员获得维护任务)很多,也许可以避免使用。
在这个具体示例中,我认为这取决于什么 lock()
做。功能昂贵吗?每次调用该功能时,它是否可以返回不同的内容(它可以第一次返回指针并第二次返回)吗?还有另一个线程可以在两个调用之间交织的线程 lock()
?
对于此示例,您需要了解 lock()
以及您的其余代码做出明智的决定。
我大部分时间都更喜欢第一个,因为它使代码更清晰,易于阅读,因此较小的错误容易发生。例如,您忘记了第二个示例上的括号:)在这种情况下,实际上,我可能会在第二个示例中做您所做的事情,但是如果我需要使用该子菜单,那么我会多几次第一个使代码更易于阅读。至于性能,我有任何理智的编译器都能对此进行优化(这可能是为什么您没有看到性能差异的原因)。
另外,正如米尔斯(Mmyers)指出的那样,这也取决于锁()的作用。通常,如果这是一种简单的Getter方法或类似的方法,您会没事的。
无论您喜欢什么。对我来说,这取决于我要使用多少;对于两行,我可能只是两次都将其写出,而如果我使用更多的话,我会创建一个变量。但是,您是很可能必须维护此代码并继续查看它的人,因此请使用适合您的任何东西。当然,如果您是一家拥有编码指南的公司,请遵循它。
我认为,首选风格是您认为代码更可读和可维护的任何样式。如果您是一个以上的团队,那么唯一的另一个考虑因素是,对于每个人来说,采用相同的风格,再次是一个好主意,再次获得可读性和易进性。
在这种情况下,我认为您应该使用临时性。即使您知道对.lock()的实现很便宜,也可能会改变。如果您不需要两次致电lock(),请不要。这里的值是将您的代码与锁定()的实现分解。一般来说,这是一件好事。