【问题标题】:Where is function overriding done?函数覆盖在哪里完成?
【发布时间】:2011-07-24 21:53:53
【问题描述】:

在创建程序、编译器、链接器等的过程中,函数的覆盖和运算符重载在哪里完成?

我对用 C++、Ruby 和 Python 完成的地方特别感兴趣。

【问题讨论】:

    标签: c++ python ruby overloading overriding


    【解决方案1】:

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

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

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

    我不知道任何支持重载的动态语言,因为理论上您可以在程序运行时引入新的重载候选者。如果存在这样的语言,我很想得到启发。

    【讨论】:

    • 这取决于您所说的“覆盖”是什么意思。 AIUI,一个非虚函数可以被覆盖,但是调用的函数是在编译时确定的。你也可以做一些有趣的事情,比如virtual void operator()();...
    • @tc- C++ 中的非虚拟函数可以重载,但不能覆盖。试图重写非虚函数只会在派生类中引入重载。
    • @tc.:不。非虚函数被隐藏,而不是被覆盖。
    • @Oboto 继承的类的虚函数通过每个类拥有的用于函数查找的 v-table。如果类A 有一个类似virtual void run(); 和类B 的函数继承自类A,并且还有另一个名为virtual void run() 的函数,那么当在任一类的实例上调用run() 时,运行-该类的 v-table 中的时间查找确定将执行哪个函数,A::runB::run。这就是使类多态成为可能的原因。
    • @Oboto 这是一个很好的链接,可以帮助您入门:parashift.com/c++-faq-lite/virtual-functions.html
    【解决方案2】:

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

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

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

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

    【讨论】:

    • Downvoter:这个答案有什么问题?这似乎完全合理。
    • @templatetypedef 我认为这是因为问题是关于覆盖和 operator 重载,而不是一般情况下的重载。
    • 好的,我已经对其进行了编辑,使其特定于运算符重载......尽管它仍然与函数重载相同......
    【解决方案3】:

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

    我也认为上述情况也适用于 Ruby。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-07
      • 1970-01-01
      • 1970-01-01
      • 2012-06-19
      • 1970-01-01
      相关资源
      最近更新 更多