이 주제의 질문은 매우 일반적인 혼란을 시사합니다. 혼란은 충분히 흔합니다. C ++ FAQ 나쁜 것으로 보였기 때문에 개인용 가상 사용을 오랫동안 옹호 입니다.
따라서 혼동을 먼저 제거하려면 : 예, 파생 클래스에서 개인용 가상 기능을 무시할 수 있습니다. 파생 클래스의 메서드는 기본 클래스에서 가상 함수를 호출 할 수 없지만 자체 구현을 제공 할 수 있습니다. Herb Sutter에 따르면 기본 클래스에 퍼블릭 비가 상 인터페이스와 파생 클래스에서 커스터마이즈 할 수있는 전용 구현을 통해 "구현 가능한 사용자 정의 동작의 사양에서 인터페이스 사양을 분리"할 수 있다고합니다. 그의 기사 "Virtuality" 에서 자세한 내용을 읽을 수 있습니다 .
그러나 당신이 제시 한 코드에는 흥미로운 점이 하나 더 있습니다. 공용 인터페이스는 오버로드 된 비가 상 함수 세트로 구성되며 해당 함수는 퍼블릭이 아닌 오버로드 된 가상 함수를 호출합니다. C ++ 세계에서와 마찬가지로이 용어는 관용구이며 이름이 있으며 물론 유용합니다. 이름은 (놀랍고 놀랍습니다!)
"퍼블릭 오버로드 된 비가 상 통화로 보호되는 오버로드되지 않은 가상"
은닉 규칙 을 올바르게 관리하는 데 도움이됩니다 . 여기 에서 자세한 내용을 읽을 수 있지만 잠시 설명하겠습니다.
Engine
클래스 의 가상 함수 도 인터페이스이며 순수한 가상이 아닌 오버로드 된 함수 세트라고 상상해보십시오 . 순수한 가상이라면 아래 설명과 같이 여전히 같은 문제가 발생할 수 있지만 클래스 계층 구조는 더 낮습니다.
class Engine
{
public:
virtual void SetState( int var, bool val ) {/*some implementation*/}
virtual void SetState( int var, int val ) {/*some implementation*/}
};
이제 파생 클래스를 만들고 싶다고 가정하고 두 개의 정수를 인수로 사용하는 메소드에 대해서만 새로운 구현을 제공해야한다고 가정 해 봅시다.
class MyTurbochargedV8 : public Engine
{
public:
// To prevent SetState( int var, bool val ) from the base class,
// from being hidden by the new implementation of the other overload (below),
// you have to put using declaration in the derived class
using Engine::SetState;
void SetState( int var, int val ) {/*new implementation*/}
};
파생 클래스에 using 선언을 넣지 않았거나 두 번째 오버로드를 재정의하는 것을 잊어 버린 경우 아래 시나리오에서 문제가 발생할 수 있습니다.
MyTurbochargedV8* myV8 = new MyTurbochargedV8();
myV8->SetState(5, true);
Engine
회원 숨기기를 막지 않았다면 다음 과 같이 진술하십시오.
myV8->SetState(5, true);
void SetState( int var, int val )
파생 클래스에서 호출 하여로 변환 true
합니다 int
.
인터페이스가 가상이 아니고 가상 구현이 공개되지 않은 경우 (예 : 파생 클래스의 경우) 파생 클래스의 작성자는 생각해 볼 문제가 적고 간단히 작성할 수 있습니다.
class MyTurbochargedV8 : public Engine
{
private:
void SetStateInt(int var, int val ) {/*new implementation*/}
};