gpt4 book ai didi

c++ - 虚函数重载

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:10:49 25 4
gpt4 key购买 nike

我在一次采访中被问到这个问题。我无法在那里回答这个问题。我现在也无法理解为什么输出是这样的。这是代码:

#include <iostream>
using namespace std;

class Base
{
public:
virtual void fun ( int x = 0)
{
cout << "Base::fun(), x = " << x << endl;
}
};

class Derived : public Base
{
public:
virtual void fun ( float x = 10.0 )
{
cout << "Derived::fun(), x = " << x << endl;
}
};


int main()
{
Derived d1;
Base *bp = &d1;
bp->fun();
d1.fun();
d1.fun(1.2);
return 0;
}

以上代码的输出为:

Base::fun(), x = 0
Derived::fun(), x = 10
Derived::fun(), x = 1.2

问题是:在第一种情况下,我们说 fun() 函数都被重载了(并且没有被覆盖,因为它们的声明不同)并且调用了基础 fun() ,但是 fun() 的这些声明不可能被重载(因为它们的区别仅在于声明是否包含默认参数)

void fun(int x = 0)
void fun(float x = 10.0)

这些函数不可能重载。

以上两种情况似乎都存在矛盾。

解释情况的任何相关文章/链接都会非常有帮助。

最佳答案

在 C++ 中,对于覆盖基类函数的成员函数,参数类型必须与基类函数的参数类型完全匹配。由于基类函数采用 int 而派生类的函数采用 float,因此它不被视为重写。您可以使用 override 关键字看到这一点:

class Base
{
public:
virtual void fun ( int x = 0)
{
cout << "Base::fun(), x = " << x << endl;
}
};

class Derived : public Base
{
public:
virtual void fun ( float x = 10.0 ) override // Doesn't compile!
{
cout << "Derived::fun(), x = " << x << endl;
}
};

您的代码中发生的情况是,C++ 将您的函数视为重载(另一个同名函数),而不是覆盖。让我们看一下这段代码:

Derived d1;
Base *bp = &d1;
bp->fun();

这里,由于 bp->fun() 行使用了通过基类指针的调用,C++ 在 Base 中查找要调用的函数。它找到 Base::fun(int)。现在,由于该函数被标记为 virtual,它将调用 Base::fun(int) 除非有什么东西覆盖了它。但是由于没有覆盖,Base::fun(int) 最终被调用。

那么后面这两行呢?

d1.fun();
d1.fun(1.2);

在这里,由于您在 Derived 静态类型的对象上调用这些函数,C++ 会尝试在 Derived 中找到名为 fun 的函数> 类。它会找到您的新函数 Derived::fun(float),并且由于 C++ 在类中查找名称的方式,它不会在基类中查找 Base::fun(int )。因此,这两个调用都被视为对 Derived::fun(float) 的调用,因此在没有提供参数时调用哪个函数没有歧义。编译器甚至从不查看 Base 类型,因为没有必要。

总结一下:

  • 您引入了重载,而不是覆盖。使用 override 关键字可以帮助您在将来诊断此类问题。
  • 通过基指针调用 fun 寻找一个名为 fun 的函数接受一个 int,因为基指针的 fun 函数接受一个 int。这会在 Base 中找到版本,因为没有 oerride。
  • 通过派生对象调用 fun 查找从 Derived 开始的名为 fun 的函数,它会找到您的覆盖。

关于c++ - 虚函数重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42816834/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com