函数重写在哪里?

时间:2011-07-24 21:53:54

标签: c++ python ruby overloading override

在创建程序,编译器,链接器等的过程中,是否覆盖了函数和运算符重载?

我特别感兴趣的是在C ++,Ruby和Python中完成它。

3 个答案:

答案 0 :(得分:4)

函数重载(至少在C ++中)在编译器内部处理。这个想法是编译器最终生成的代码将被硬编码以调用适当的函数,就好像函数都具有不同的名称并且您调用了唯一适合参数的函数。更一般地,在支持重载的大多数编译语言中,重载解析在编译时完成,并且发出的代码将始终调用指示的函数。例如,Haskell以这种方式支持编译时重载。

运算符重载是一般重载的特例,因此通常以相同的方式处理。

函数覆盖(当派生类继承自基类并重新定义其中一个方法时,在OOP中出现的术语)几乎总是在运行时解析,因为编译器不能总是告诉在没有真正了解运行时类型的情况下调用哪个函数。有些编译器可能能够静态地证明某个对象具有特定类型,然后可以优化动态调度,但在所有情况下都不可能这样做。

我不知道任何支持重载的动态语言,因为理论上你可以在程序运行时引入新的重载候选。如果存在这样的语言,我希望能够开悟。

答案 1 :(得分:3)

对于C ++,运算符重载是在编译器级别通过名称修改过程完成的,该过程为每个函数创建唯一的名称标识符,以便链接器不会抱怨重复的函数定义。在C ++中,运算符重载是可能的,因为+-*等可重载操作本身就是实际函数,其前缀为operator,后跟符号操作。例如,一个带有函数签名的重载operator+函数,如

my_type operator+(const my_type& lhs, const my_type& rhs);

不会与具有不同签名的另一个operator+函数冲突,即使两个函数具有相同的operator+名称,因为该函数的每个版本在汇编语言级别具有不同的名称在C ++编译器的名称修改过程完成之后。名称修改还有另一个好处,即允许C和C ++编译的代码与同一个链接器一起使用,因为两个具有相同名称的函数将不存在并导致链接器错误。

请注意,在C中,即使您创建具有不同签名的两个函数,如果它们具有相同的名称,由于C编译器不会进行任何名称修改,链接器将会抱怨该函数的重复定义。

答案 2 :(得分:0)

Python没有链接/编译,它被解释。 因此,在解析类源时会执行正常的重写。当然,由于动态特性,您也可以在运行时期间覆盖。 我想使用byto-code编译的替代实现是在编译时完成的。

我也认为上面的内容也适用于Ruby。