2011-09-12 5 views
1

B 클래스는 A 클래스에서 파생됩니다. 그 둘은 f()을 선언합니다. f가 보호됩니다. 따라서 f는 A 내부와 B 내부에서만 호출됩니다. f()을 가상으로 선언해야합니까?가상 기능이 필요하지 않습니다.

B에서 파생됩니다. A에서 파생됩니다. BA은 보호되지 않은 가상으로 보호 된 것으로 선언합니다. f(). CBf()으로 전화하면 B::f()과 A으로 해결됩니까?

그런 경우, 보호 된 구성원이 정적 인 해결 방법을 사용하려면 항상 가상을 피해야합니까? 이 작업이 자동으로 수행됩니까? 감사!

+2

산문 대신 코드로 작성하면 더 좋을 것입니다. – PlasmaHH

+0

관심 분야 : http://www.gotw.ca/publications/mill18.htm – Flexo

답변

1

다형성 동작 (예 : Template Method pattern)을 사용하려면 보호 방법 virtual을 선언해야하며 그렇지 않을 경우에는 피해야합니다. 그러나 후자의 경우 하위 클래스에서 같은 서명을 가진 다른 함수로 함수를 숨기면 안됩니다. 그렇지 않으면 미묘한 버그 가능성을 열어주는 수수께끼 같은 동작 (두 번째 단락에서 설명하는 것과 같은)이 발생합니다. ...

+0

이 경우에도 다형성 행동이란 무엇입니까? 그게 기본 클래스에 대한 포인터를 가지고 있다고 가정하지 않습니까? 이것은 정의에 의해 공공 기능 접근을 필요로하지 않습니까? – Cookie

+0

@ 쿠키 번호. A에서 (외부에서) 호출하거나 C 또는 B에서 다시 구현/오버로드하지 않은 모든 함수에서 'this'는 A에 대한 포인터이므로 A 메서드 만 알고 있고 호출 된 메소드가 가상이 아닌 경우 런타임에 해석되지 않고 A 메소드를 얻습니다. –

+0

@ 쿠키, 아니요, 공개 액세스가 필요 없습니다. 'A'에서 선언 된'protected virtual' 메쏘드를 호출하고 다른 서브 클래스에서 오버라이드 된 public 메소드를 생각해보십시오. 'protected' 메소드를 통해 다형성 동작을 얻습니다. 자세한 내용은 * Template Method *에 대한 참조를 참조하십시오. –

0

나는 내 C에 약간 녹슨입니다 ++하지만 난 당신이 방법 private을 선언하고, 따라서 당신이 당신의 시나리오에서 protected과 함께 virtual을 필요로 할 때 "고정 해상도가"에만 보장 될 것이라고 말할 것입니다 f()에 대한 호출이 A에서 파생 된 함수에서 수행되고 (B 또는 C에 오버로드되거나 다시 구현되지 않은) this 포인터는 A*으로 결정되므로 A::f()이 호출됩니다. 따라서이 경우에는 가상 함수가 필요합니다.

+1

당신은 실제로 [개인 가상 함수] (http : // stackoverflow.com/questions/2170688/private-virtual-method-in-c)를 사용하면 동적으로 바인드됩니다. Java와 C#, IIRC에서 privates는 실제로 overrideable 할 수 없으므로 정적으로 바인딩됩니다. – eran

2

로를

0

그래서 :

class A { 
public: 
    void f() { std::cout << "A::f\n"; } 
}; 

class B : public A { 
public: 
    void f() { std::cout << "B::f\n"; } 
}; 

만큼 컴파일러는 객체가 B가 실제로 것을 알고, 그것은이 항상 사실이 아니다, B에서 F()를 호출하지만 것

void callF(A* a) 
{ 
    a->f(); 
} 

B b; 
callF(&b); // prints A::f 

callF과 같은 함수가 올바른 f() 함수를 호출하도록하려면 virtual으로 지정하십시오. 일반적으로 자손 클래스에서 재정의하는 것이 합리적이라면 함수를 가상으로 만듭니다. 이것은 종종 보호 된 기능의 경우입니다.

+0

죄송 합니다만,이 예제는'f()'를 public으로 가정합니다. – Cookie

관련 문제