2012-06-03 6 views
7

아래 코드의 결과가 "클래스 B :: 1"이되는 이유를 설명 할 수 있습니까?코드는 파생 클래스 메서드를 실행하지만 기본 클래스 메서드에서 기본 매개 변수를 가져옵니다

파생 클래스의 가상 메소드가 기본 클래스의 기본 매개 변수를 사용하고 자체 클래스의 기본 매개 변수를 사용하는 이유는 무엇입니까? 제게 이것은 꽤 이상합니다. 미리 감사드립니다!

코드 : 기본 값이 컴파일시 대체하고 실제 함수가 (A : FUNC 또는 B : FUNC)를 호출 할 때 런타임에 결정, 선언에서 가져

#include <iostream> 

using namespace std; 

class A 
{ 
public: 
    virtual void func(int a = 1) 
    { 
     cout << "class A::" << a; 
    } 
}; 

class B : public A 
{ 
public: 
    virtual void func(int a = 2) 
    { 
     cout << "class B::" << a; 
    } 
}; 

int main() 
{ 
    A * a = new B; 
    a->func(); 

    return 0; 
} 

답변

6

기본 인수는 정적 유형에 따라 결정되므로 this (즉, A& a;A&과 같은 변수 자체의 유형).

약간 예 수정 :

#include <iostream> 

class A 
{ 
public: 
    virtual void func(int a = 1) 
    { 
     std::cout << "class A::" << a << "\n"; 
    } 
}; 

class B : public A 
{ 
public: 
    virtual void func(int a = 2) 
    { 
     std::cout << "class B::" << a << "\n"; 
    } 
}; 

void func(A& a) { a.func(); } 

int main() 
{ 
    B b; 
    func(b); 
    b.func(); 

    return 0; 
} 

우리는 다음과 같은 출력을 관찰 : 액션에서

class B::1 
class B::2 

ideone에서.

가상 기능으로 인해이 값이 기본값으로 변경되는 것은 바람직하지 않습니다. 불행히도 나는이 구조에 대해 경고하는 컴파일러를 모른다.

  • 이 트램 폴린 역할을 할 수있는 새로운 기능을 만들 :


    기술적 인 해설은 기본 인수를 처리하는 방법은 두 가지가 있다는 것입니다 void A::func() { func(1); }

  • 추가 통화에서 누락 된 인수 사이트 a.func() =>a.func(/*magic*/1)

는 전이라면 (그리고 그 가정 A::func와트 예 : virtual), 예상대로 작동합니다. 그러나 후자의 형태는 virtual과 관련된 이슈가 당시에는 예측되지 않았거나 혜택 (있을 경우 ...)에 비하면 중요하지 않은 것으로 간주 되었기 때문에 선출되었습니다.

5

때문입니다.

+0

빠른 답변 주셔서 감사합니다. – Aremyst

5

C++의 다형성은 런타임에 적용되기 때문에 기본 매개 변수의 대체는 컴파일 타임에 적용됩니다. 컴파일시 컴파일러는 a 포인터가 가리키는 객체의 동적 유형을 알지 못합니다 (알지도 못합니다). 따라서 예를 들어 A *a에 대해 알고있는 유일한 유형의 기본 인수가 필요합니다.

는 (이 우연히 또한 매개 변수가 아니라 구현/정의에 비해 인터페이스/헤더에 주어진 이유 기본값입니다. 컴파일러는하지만, 단지 발신자의 컴퓨터 코드, 구현의 기계 코드의 기본 매개 변수를 삽입하지 않습니다. 기술적으로 , 기본 매개 변수는 호출자의 속성이며 호출자는 객체의 동적 유형을 알지 못하므로 알 필요가 없습니다.

+0

답변이 매우 명확합니다. 감사합니다. – Aremyst