As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center提供指导。




已关闭10年。




这段代码:
if( someCondition )
    return doSomething();

return doSomethingElse();

与下面的代码:
if( someCondition )
    return doSomething();
else
    return doSomethingElse();

从本质上讲,它们是相同的,但是最好的样式/性能/...(当然,答案中是否包含未修饰的部分)是什么?还考虑带有多个“if else”的情况:
if( someCondition )
    return doSomething();
else if( someOtherCondition )
    return doSomethingDifferently();
//...
else
    return doSomethingElse();

谢谢!

最佳答案

当一个函数中有多个return语句时,这称为“早期返回”。如果为“早日返回”执行Google search,则您会在链接之后找到表示不好的链接。

我说废话

人们声称提早退货是不好的,这有两个主要原因和一个次要原因。我将仔细研究它们,并按顺序进行反驳。请记住,这是我的全部观点,最终您必须自己决定。

1)原因:过早的返回难以清理。

反驳:这就是RAII的目的。设计良好的程序不会以这样的方式分配资源:如果执行提前离开范围,这些资源就会泄漏。而不是这样做:

...

int foo()
{
  MyComplexDevice* my_device = new MyComplexDevice;
  // ...
  if( something_bad_hapened )
    return 0;
  // ...
  delete my_device;
  return 42;
}

你做这个:
int foo()
{
  std::auto_ptr<MyComplexDevice> my_device(new MyComplexDevice);
  if( something_bad_hapened )
    return 0;
  // ...
  return 42;
}

尽早返回不会造成资源泄漏。在大多数情况下,您甚至不需要使用auto_ptr,因为您将创建数组或字符串,在某些情况下,您将使用vectorstring或类似的东西。

由于存在异常的可能性,因此您仍然应该像这样设计代码以提高鲁棒性。异常是一种提前返回的形式,例如一个显式的return语句,您需要做好应对它们的准备。您可能无法在foo()中处理该异常,但是无论如何,foo()不应泄漏。

2)原因:过早的返回使代码更加复杂。
反驳:早期的返回实际上使代码更简单。

职能应负一个责任是一种普遍的哲学。我同意这一点。但是人们对此太过分了,得出的结论是,如果一个函数具有多个返回,则它必须承担多个责任。 (他们通过说函数的长度不能超过50行或其他任意数字来扩展这一点。)我说不。仅仅因为一个功能只有一个责任,并不意味着它没有太多的工作可以实现这种可重复性。

以打开数据库为例。这是一项责任,但它由许多步骤组成,每个步骤都可能出错。打开连接。登录。获取一个连接对象并返回它。 3个步骤,每个步骤都可能失败。您可以将其分解为3个子步骤,但不要像这样编写代码:
int foo()
{
  DatabaseObject db = OpenDatabase(...);
}

您最终将拥有:
int foo()
{
  Connection conn = Connect(...);
  bool login = Login(...);
  DBObj db = GetDBObj(conn);
}

因此,您实际上只是将假定的多个职责移到了调用堆栈中的更高位置。

3)原因:多个返回点不是面向对象的。
反驳:这实际上是另一种说法,“每个人都说多次返回不好,尽管我真的不知道为什么。”

换句话说,这实际上只是将所有内容塞入对象形状的盒子的尝试,即使它不属于该对象。当然,也许连接是一个对象。但是是登录名吗?登录尝试不是(IMO)对象。它是一个操作。或算法。尝试采用此算法并将其塞入对象形状的框是OOP的无偿尝试,只会导致代码更复杂,更难以维护,甚至可能效率更低。

关于c++ - 是否没有 “if(…) return …;”的 “else”被认为是好的样式? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4238063/

10-11 23:18
查看更多