【问题标题】:Overload a method or use default values? c++重载方法还是使用默认值? C++
【发布时间】:2013-04-08 10:16:46
【问题描述】:

我对 C++ 还是比较陌生,我似乎无法弄清楚以下两种编码可能采用一个参数或两个或三个或更多参数的函数的方式的区别。无论如何,这是我的观点

函数重载:

int aClass::doSomething(int required)
{
    //DO SOMETHING
}

int aClass::doSomething(int required, int optional)
{
    //DO SOMETHING
}

这与默认值有何不同:

int aClass::doSomething(int required, int optional = 0)
{
    //DO SOMETHING
}

我知道在不同的情况下,其中一种可能比另一种更合适,但在这些选项之间进行选择时我应该注意哪些事项?

【问题讨论】:

  • 非静态数据成员不能作为默认值;例如int MyFoo::doSomething(int optional=MyFoo::n)

标签: c++ overloading default


【解决方案1】:

有几个技术原因更喜欢重载而不是默认参数,它们在 Google 的 C++ Style Guide 中的 Default Arguments section 中有很好的布局:

在存在默认参数的情况下,函数指针会令人困惑, 因为函数签名通常与调用签名不匹配。 向现有函数添加默认参数会更改其类型, 这可能会导致代码获取地址出现问题。添加功能 重载可以避免这些问题。

和:

默认参数可能会导致代码更庞大,因为它们是 在每个调用点复制——而不是重载函数, 其中“默认”仅出现在函数定义中。

积极的一面是:

通常你有一个使用默认值的函数,但偶尔 你想覆盖默认值。默认参数允许一个简单的 无需为罕见的函数定义许多函数的方法 例外。

因此,您的选择将取决于负面问题与您的应用程序的相关程度。

【讨论】:

    【解决方案2】:

    首先,您说的是重载,而不是覆盖。对派生类中的virtual 函数进行了覆盖。重载指的是同一个函数名不同的签名。

    区别在于逻辑 - 在第一种情况(2 个版本)中,两个函数的行为可能完全不同,而第二种情况的逻辑或多或少是相同的。这完全取决于你。

    【讨论】:

      【解决方案3】:

      编译器并不关心你使用哪一个。想象一下,你把它写成两个构造函数,它们最终有大约 20 行长。进一步想象有 19 行是相同的,而不同的行读取

      foo = 0;
      

      在一个版本中和

      foo = optional;
      

      在另一个。在这种情况下,使用可选参数会使您的代码更具可读性和可理解性。在另一种没有可选参数的语言中,您可以通过让单参数版本调用双参数版本并将零作为第二个参数传递给它来实现。

      现在想象一对不同的构造函数或函数,它们同样长约 20 行,但完全不同。例如,第二个参数是一个 ID,如果提供,则在数据库中查找内容,如果不是,则将值设置为 nullptr、0 等。你可以有一个默认值(-1 很受欢迎)但是函数的主体将充满

      if (ID == -1)
      {
          foo = 0;
      }
      else 
      {
          foo = DbLookup(ID);
      }
      

      这可能难以阅读,并且会使单个函数比两个单独的函数长得多。我见过一个巨大的函数if,它本质上将整个事情分成两个单独的块,没有公共代码,我已经看到随着计算的进行,相同的条件测试了 4 或 5 次。两者都很难阅读。

      这就是 C++ 的特点。有很多方法可以完成大多数事情。但是这些不同的方式服务于不同的目的,一旦你“得到”了细微的差异,你就会写出更好的代码。在这种情况下,“更好”意味着更短、更快(所有这些 ifs 都会花费执行时间)和更具表现力 - 阅读它的人可以快速理解您的意图。

      【讨论】:

        【解决方案4】:

        如果您提供多个constructors,则您正在使用重载功能。这种情况下的优点是,您可以在每个 constructor 中对传递的参数做出不同的反应。如果这很重要,请使用重载。
        如果您可以为您的参数提供合适的default 值并且这些值不会影响您的代码的正常运行,请使用默认参数。

        请参阅here 了解关于 SO 的主题。

        【讨论】:

          猜你喜欢
          • 2023-03-17
          • 2016-06-22
          • 2022-01-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-10
          相关资源
          最近更新 更多