2017-03-15 79 views
3

我在面试中被问到这个问题。我无法在那里回答这个问题。我现在也无法得知它,为什么产量是这样。 下面是代码:虚拟功能的超载

#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()的这些声明是不可能被重载的(因为它们只是区别声明是否包含默认参数)

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

这些函数不可能被重载。

在上述两种情况下似乎都有矛盾。

任何相关的文章/链接解释情况将是非常有益的。

+0

你期望输出是什么?为什么? – NathanOliver

+0

在第一种情况下,由于运行时多态性,输出应该是Derived :: fun(),x = 10.0。在第二和第三种情况下,你如何决定输出? –

回答

8

在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类型,因为没有必要。

因此,要总结:

  • 你介绍一个超载,不是覆盖。使用覆盖关键字将有助于您在将来诊断此类问题。
  • 通过基指针调用fun查找名为fun功能以在int,因为基指针的fun功能发生在一个int。这在Base找到版本,因为没有oerride。
  • 通过派生对象调用fun查找函数fun,从Derived开始,它会查找您的覆盖。
+0

在第一种情况下,为什么运行时多态性不存在? –

+1

@YamanSingla刚刚更新了解释发生了什么事的答案。 – templatetypedef

+0

非常感谢@templatetypedef的帮助。我现在明白了究竟发生了什么! –