为什么函数重载被添加到C++中?

Cur*_*eek 30 c c++ overloading

我有一个C背景.我只是想知道为什么函数重载被添加到C++中?C没有函数重载但是C++没有,它需要什么?

当时语言设计师的想法是什么?

Pup*_*ppy 54

它增加了可维护性.如果你有一个类型T并用它调用一个函数,那么你需要更改T,如果该函数已经为新T重载,那么你可以立即重新编译.在C中,您必须返回并浏览所有呼叫站点并更改所调用的功能.拿sqrt().如果你想要sqrt()一个浮点数,那么你必须改为sqrtf().

不仅如此,C++类型系统的体积和复杂性远远超过C,并且必须为每个可能的重载分别具有单独的函数名称,这很快就会耗尽合理的名称池,这些函数用于同样的目的,但却采用不同的参数,因为现在有更多的争论要采取.

例如,比较C和C++字符串库.C字符串库提供了一种附加到字符串的方法 - strcat().C++的std :: string :: append有8个重载.你想叫他们什么?append_a,append_b等?这太荒谬了 - 他们都以不同的方式服务于同样的功能.

编辑:这真正值得一提的append是一个非常糟糕的例子,许多C++字符串重载是非常多余.但是,这种情况比这更普遍,并非所有这些过载都是多余的.

  • 重载也会插入C类型系统中的一些漏洞,例如`strchr`.有一个单一的名称是非常可取的,C甚至没有*具有const正确的版本.无论参数的类型如何,安全性显然被认为不如能够使用相同的名称(`strchr`)重要.对我来说,这是一个很好的例子,如果你喜欢const足够把它放在你的类型系统中,你真的应该更喜欢重载. (15认同)
  • `sqrt()`vs`sqrtf()`实际上是个坏例子.标准sqrt()函数接受(并返回)一个双精度浮点数,因此单精度浮点数就可以正常工作.添加了`sqrtf()`函数,以便人们可以有意选择使用单精度浮点数学,这在某些硬件上可能更快.如果你想要基于输入类型的精度或速度,函数重载不能(或至少*不应该*!)猜测.无论如何,这必须是一个单独的参数或另一个函数. - mattdm 22分钟前 (4认同)
  • @R:函数重载是一种通用编程.模板只是类型中的通用(以及特定的非类型参数)的一个示例,您不能使用模板来替换append的重载.operator <<是函数重载的一个很好的例子,因为它很容易扩展.如果你不知道你是在一个int还是在一个流上使用<<,那么你就会遇到更大的问题.@mattdm:如果你想改变你的浮点数的精度,你就投了.这就是一切工作的原因 - 为什么不进行函数调用? (3认同)

Stu*_*etz 22

除了DeadMG所说的,一个很好的理由是,如果你正在编写一个模板函数,例如调用sqrt,那么你需要一种通用的调用方式sqrt- 如果你不得不尝试以某种方式改变名称将是非常困难的to sqrtf,sqrtd等等,具体取决于模板参数的类型.重载解决了这个问题,因为那样你只需编写sqrt并让编译器找出它应该使用的重载:

template <typename T>
T sqrt_plus_one(T t) // contrived example
{
  return sqrt(t) + 1;
}
Run Code Online (Sandbox Code Playgroud)

  • @JeremyP:模板是一种重载的形式,并且在函数的情况下,特化具有一些令人惊讶的属性,在某种程度上,部分模板函数特化被认为*比没有它更糟糕,因此在C++ 03中不允许.要限制重载,以便模板专业化是它的唯一形式,你必须解决这些问题(我不记得细节,但随意提出修复......) (3认同)
  • 如果你打算使用模板,你可以模板`sqrt()`然后你不需要重载. (2认同)

Naw*_*waz 15

你更喜欢在abs/labs/llabs/fabs/fabsf/fabsl中选择一个还是只选择abs()

显然,abs().

因此,除了其他优点之外,大多数情况下,函数重载对程序员来说是一种解脱.

  • @R,为什么两个论点互相排斥?针对同样问题的不同答案.这就像说小型货车不是大家庭的答案,因为SUV存在. (7认同)

NPE*_*NPE 12

您可以直接从马的口中得到答案:Bjarne Stroustrup 的C++设计和演变将整整一章用于重载,历史,演变,设计权衡和决策.

我不会在这里讲述这个故事,但会提到一些有趣的历史事实:

  • 运算符和函数重载密切相关;
  • 在早期的C++中,曾经有一个特殊的关键字(overload)必须用于将标识符声明为重载;
  • 函数重载需要类型安全的链接(即名称修改); 在第一次实现时,它帮助在现有的C和C++代码中发现了惊人数量的链接时错误(引用Stroustrup,它就像是" lint第一次在C程序上运行- 有点尴尬".)