2009-05-13 8 views
18

클래스 B에서 가상 함수 foo()가 있다고 가정하고 B의 파생 클래스 인 클래스 D 중 하나에서 약간 다른 동작이 필요합니다. 재정의 함수 D :: foo를 만들면 괜찮습니까?()를 호출하고 B :: foo()를 호출합니다. 이와 같이 :재정의 함수에서 재정의 된 함수 호출

void D::foo() 
{ 
    if (/*something*/) 
    // do something 
    else 
    B::foo(); 
} 

나는 그것이 효과가 있는지 묻지 않습니다. 좋은 OOD의 관점에서 올바른지 여부를 알고 싶습니다.

답변

17

이것은 아주 좋습니다. 사실, 일부 작업을 수행하는 정식 방법은 기본 클래스 메서드를 호출 한 다음 (또는 다른 방법으로) 수행합니다. 나는 operator=을 여기에서 생각하고있다. 생성자는 초기화 목록에서 조금 위장한 경우에도 보통 그렇게 작동합니다.

4

예, 그렇습니다.

+3

은, 일반 표준, 일반 전형, 널리 사용. 사실,이 작업을 수행하는 것이 절대적으로 중요합니다. –

1

GUI 프레임 워크에서 오류를 신호로 보내거나 예외를 throw하거나 일반적인 값을 반환하는 코드가 포함 된 기본 클래스의 기본 구현으로 되돌아가는 것을 보았습니다.

5

예, Liskov 대체 원리를 위반하지 않는 한 완전히 괜찮습니다.

0

네, 그것은 컴파일러가 생성자와 소멸자를 생성 할 때마다 당신의 컴파일러가하는 것입니다. 예를 들어 어머니의 것을 호출합니다. 나는 종종 내 자신의 코드에서 "트릭"에 의존한다.

1

괜찮습니다. 구문은 일시적으로 다형성을 끄는데도 사용할 수 있습니다. 즉, foo()가 가상인지 아닌지에 관계없이 클래스 B에서 foo() 메서드가 선택되고 obj가 B의 인스턴스 인 경우 foo() 메서드가 선택됩니다. 또는 아닙니다 (B를 확장하는 클래스의 인스턴스 여야합니다).

+0

_B_의 하위 클래스에서 함수가 호출되지 않는다고 보장 할 수는 없습니다.이 경우 아무 것도 돌리지 않습니다. – xtofl

+0

@xtofl : B 확장 A, C 확장 B, 즉 A B :: foo()를 호출하면 A ::를 호출 할 수 있다고 말합니다. foo()? –

+0

@xtolf : 방금 내 대답을 확인했으며 올바른 것으로 보입니다. –

0

기본 구현을 호출해도 괜찮지 만 조건부로을 사용하면 다른 답변에서 제안 된 것과는 달리 생성자 의미론에서 벗어날 수 있습니다.

는 두 가지 방법으로 fragile base class 문제로 실행할 수 있습니다 : B::foo()을 가정하여

  • (즉, 방법을 잊어하는 것은 항상 호출되지 않습니다)
  • 음란 문제에 따라 전체 계층 구조에 대한 일반적인 동작을 제공하는 것 // do something 실제로 않습니다!

완성도를 들어, 대칭 설계 방식을 언급하자 Template pattern (기본 구현 호출 특정 하위 부분)