我仍然相对较新的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
}
我知道在不同的情况下,一个人可能比另一个更合适,但在选择这些选项时,我应该注意哪些事情?
答案 0 :(得分:16)
有几个技术原因需要重载到默认参数,它们在C++ Style Guide的Google Default Arguments section中得到了很好的规划:
在存在默认参数时,函数指针会混淆, 因为功能签名通常与呼叫签名不匹配。 向现有函数添加默认参数会更改其类型, 这会导致代码占用其地址时出现问题。添加功能 超载避免了这些问题。
和
默认参数可能会导致代码更庞大,因为它们是 在每个呼叫站点复制 - 而不是重载功能, 其中“默认值”仅出现在函数定义中。
积极的一面是:
通常你有一个使用默认值的函数,但偶尔会有 你想要覆盖默认值。默认参数可以轻松实现 这样做的方式,而不必为罕见的定义许多功能 异常。
因此,您的选择将取决于您的申请的负面问题的相关程度。
答案 1 :(得分:6)
首先,你在谈论重载,而不是覆盖。覆盖派生类中的virtual
函数。重载是指具有不同签名的相同函数名称。
差异是合乎逻辑的 - 在第一种情况下(2个版本),两个函数可以表现完全不同,而第二个案例将具有或多或少相同的逻辑。这完全取决于你。
答案 2 :(得分:4)
编译器不关心您使用哪些。想象一下,你把它写成两个构造函数,它们最终约为20行。进一步想象,19条线是相同的,不同的线读
foo = 0;
在一个版本和
foo = optional;
在另一个。在这种情况下,使用可选参数可使代码更易读和理解。在另一种没有可选参数的语言中,您可以通过让单参数版本调用两个参数版本并将其作为第二个参数传递给零来实现此目的。
现在假设一对不同的构造函数或函数再次大约20行但完全不同。例如,第二个参数是一个ID,如果提供了它,则在数据库中查找内容,如果不是,则将值设置为nullptr
,0,依此类推。你可以有一个默认值(-1很受欢迎)但是函数体将充满
if (ID == -1)
{
foo = 0;
}
else
{
foo = DbLookup(ID);
}
这可能很难阅读,并且会使单个功能比两个独立的功能更长。我已经看到一个巨型if
的函数将整个事物分成两个独立的块,没有共同的代码,我看到相同的条件测试了4到5次计算进展。两者都难以阅读。
这就是关于C ++的事情。有很多方法可以完成大多数事情。但是这些不同的方式有不同的用途,一旦你“得到”微妙的差异,你就会编写更好的代码。在这种情况下,“更好”意味着更短,更快(所有那些if
的成本执行时间),并且更具表现力 - 阅读它的人可以快速理解您的意图。
答案 3 :(得分:2)
如果您提供多个constructor
,则表示您正在使用重载功能。在这种情况下的优点是,您可以在传递的参数的每个constructor
中做出不同的反应。如果重要的是使用重载。
如果您可以为参数提供合适的default
值,这些值不会影响代码的正常运行,请使用默认参数。
请参阅here了解SO上的帖子。