2017-03-15 10 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++이 기능은 오히려 재정보다 과부하 (동일한 이름을 가진 다른 함수)으로 간주한다는 것이다. 의이 코드를 살펴 보자 : 라인 bp->fun()가 기본 클래스 포인터를 통해 전화를 사용하기 때문에, C++ 호출하는 기능을하는 볼 Base에 보이는

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

. 그것은 Base::fun(int)을 찾습니다. 이제 그 기능이 virtual으로 표시 되었기 때문에 무언가를 넘치지 않는 한 Base::fun(int)을 호출합니다. 그러나 오버라이드가 없으므로 Base::fun(int)이 호출됩니다.

그럼 나중에 두 줄은 어떻게됩니까? 당신이 정적 유형 Derived의 객체에이 함수를 호출하고 있기 때문에 여기에

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

는 C + +를 Derived 클래스 fun를라는 함수를 찾습니다. 그것은 당신의 새로운 함수 Derived::fun(float)을 찾고, C++이 클래스에서 이름 검색을하기 때문에 기본 클래스에서 Base::fun(int)을 찾지 않습니다. 따라서이 두 호출은 Derived::fun(float)에 대한 호출로 처리되므로 인수가 제공되지 않을 때 호출 할 함수에 대한 모호성은 없습니다. 컴파일러는 심지어 필요가 없었기 때문에 Base 유형을 보지 못했습니다.그래서

는 요약 : 당신은 과부하 아닌 재정을 도입했습니다

  • . 재정의 키워드를 사용하면 향후 이와 같은 문제를 진단하는 데 도움이됩니다. 기본 포인터의 fun 함수는 int에 걸리므로 기본 포인터를 통해 fun를 호출
  • int에 복용 fun라는 함수를 찾습니다. 그것은 외계인이 없기 때문에 Base의 버전을 찾습니다.
  • 파생 된 개체를 통해 fun을 호출하면 fun부터 시작하는 함수가 Derived으로 시작되며 재정의를 찾습니다.
+0

첫 번째 경우, 런타임에 다형성이없는 이유는 무엇입니까? –

+1

@ YamanSingla 방금 무슨 일이 벌어 졌는지 설명하도록 답변을 업데이트했습니다. – templatetypedef

+0

@templatetypedef 도움말에 감사드립니다. 나는 실제로 무슨 일이 벌어지고 있는지 이해했다! –