2012-04-20 2 views
5

기본 클래스 A에는 하위 클래스 B이 있고 B에는 하위 클래스 C이 있습니다. A은 가상 메서드 doStuff(), B을 구현하지 않으며 C을 구현합니다. C에서, 나는 A 전화를 걸 '(doStuff()의의 구현 doStuff()의의 구현을 나는 C 내에서이 작업을 수행 할'하지만 그건별로 중요하지 않아야합니다.) 내가 전화를해야 :기본 클래스에서 동일하게 명명 된 메서드 호출

A::doStuff(); 

또는 :

B::doStuff(); 

첫 번째는 실제 구현을 나타 내기 때문에 더 분명합니다. 한편, 나중에 BdoStuff()과 다를 경우 A과 다른 것으로 결정하면 두 번째 것이 더 유용 할 수 있습니다. 어느 것이 더 표준인가? 어느 것이 더 위험한가요?

B::doStuff() 경고가 발생하지 않았다는 사실에 약간 놀랐지 만, 기본 클래스의 경우에도 B에 구현이 있다고 가정합니다. 기본 클래스와 구현 체인이 임의로 길고 복잡 할 수 있습니까? 예를 들어, A에서 Z까지 각각의 서브 클래스가 있는데, 체인의 어디에서나 구현할 수 있으며, 구현을 찾을 때까지 모든 클래스의 메소드를 '체인'위로 이동시킬 수 있습니까?

답변

2

첫째, 마지막 단락과 관련하여 네가 절대적으로 옳습니다.

다음은 주요 질문 :

그것은 사례별로 처리해야 논리의 문제입니다. B::doStuff()이 아직 구현되지 않은 경우에도 B 또는 A에서 논리를 호출할지 여부를 결정할 수있는 유일한 사람은 귀하뿐입니다. 정답은 없습니다.

그러나 템플릿 방법 패턴을 조사해야합니다. 제 생각 엔 에서 무엇인가를 호출하고 싶은 경우에 D (형제는 C)이 동일한 작업을 수행하기를 원한다면 코드를 복제하려고합니다. 그래서 나는 다른 접근법을 택할 것입니다 :

class A 
{ 
private: 
    void doAStuff(); //doesn't have to be here 
public: 
    virtual void doStuff() 
    { 
     doAStuff(); 
    } 
    void doAStuffAndStuff(); 
    { 
     doAStuff(); 
     doStuff(); 
    } 
} 

class B : A 
{ 
public: 
    virtual void doStuff(); //or not 
} 

class C : B 
{ 
public: 
    virtual void doStuff(); 
} 

IMO 더 직관적입니다. 내가 가장 파생 클래스의 논리 doStuff()를 호출 할 경우

  • , 나는 doStuff() 전화 : 나는 a의 동적 유형을 모르는, 내가 A* a을 말해봐.
  • doStuff()을 가장 파생 된 클래스의 논리로 호출하려는 경우 A의 논리를 원하지만 doAStuffAndStuff()이라고합니다.

나는이 접근법을 대안으로 말하고있다. 나는 그것이 반드시 귀하의 사건에 적용된다고 말하는 것은 아니지만 그것은 가능할 수 있습니다.

+0

아주 깔끔하고 유용한 대안처럼 보입니다. – Luke

0

B::doStuff으로 전화하십시오. 가능한 경우 기본 클래스의 메서드를 명시 적으로 호출해야하는 디자인을 사용하지 마십시오.필요한 경우 정확히 그런 종류의 오류를 방지하려면 base.doStuff을 일부 매크로 또는 별칭으로 시뮬레이트하십시오. 별칭을 정의하고 (컴파일 타임에 해당 존재 여부 확인) BaseType 클래스에서 BaseType::doStuff 구문을 사용할 수 있습니다.

나는 B : doStuff()가 경고를 트리거하지 않았다 조금 놀랐습니다,하지만 난 정의 B가 기본 클래스에서 경우에도 구현을가함으로써

가 있다고 가정 경고 할 것이 없다. 그것은 귀하의 경우에 합법적 인 시나리오입니다.

는 기본 클래스와 구현 체인 복잡한

가 네, 할 수있는 임의의 길이 될 수 있지만, 그것은 안된다. 긴 상속 체인을 필요로하는 디자인과 숨겨진 규칙을 포함하는 디자인 기본 클래스가 호출되어야하는 메소드는 일반적으로 손상됩니다.