모든 가상 함수를 파생 클래스에서 구현해야합니까? 질문처럼 보일지 모르지만

이것은 간단한 질문처럼 보일지 모르지만 다른 곳에서는 답을 찾을 수 없습니다.

다음이 있다고 가정합니다.

class Abstract {
public:
    virtual void foo() = 0;
    virtual void bar();
}

class Derived : Abstract {
public:
    virtual void foo();
}

Derived 클래스가 bar () 함수를 구현하지 않는 것이 괜찮습니까? 내 모든 파생 클래스에 bar () 함수가 필요한 것은 아니지만 일부는 필요합니다. 추상 기본 클래스의 모든 가상 함수를 파생 클래스에서 구현해야합니까, 아니면 순수 가상 인 것만 구현해야합니까? 감사



답변

파생 클래스는 자체적으로 모든 가상 함수 를 구현할 필요가 없습니다 . 그들은 순수한 것을 구현하기 만하면 됩니다. 1 이것은 질문 의 클래스가 맞다는 것을 의미합니다 . 그것은 상속 조상 클래스의 구현을 . (이것은 어딘가에 구현되어 있다고 가정합니다 . 질문의 코드는 메서드를 선언하지만 정의하지는 않습니다. Trenki의 답변에 표시된 대로 인라인으로 정의하거나 별도로 정의 할 수 있습니다.)DerivedbarAbstractAbstract::bar


1 그리고 심지어 파생 클래스가 인스턴스화 되는 경우에만 . 파생 클래스가 직접 인스턴스화되지 않고 더 많은 파생 클래스의 기본 클래스로만 존재하는 경우 모든 순수 가상 메서드를 구현하는 것은 해당 클래스입니다. 계층 구조의 “중간”클래스는 기본 클래스와 마찬가지로 일부 순수 가상 메서드를 구현하지 않은 상태로 둘 수 있습니다. “중간”클래스 순수 가상 메서드를 구현하는 경우 그 후손은 해당 구현을 상속하므로 직접 다시 구현할 필요가 없습니다.


답변

순수 가상 메서드 만 파생 클래스에서 구현되어야하지만 다른 가상 메서드에 대한 정의 (단순한 선언이 아닌)가 여전히 필요합니다. 하나를 제공하지 않으면 링커가 불평 할 수 있습니다.

따라서 {}선택적 가상 메서드 뒤에두면 빈 기본 구현이 제공됩니다.

class Abstract {
public:
    virtual void foo() = 0; // pure virtual must be overridden
    virtual void bar() {}   // virtual with empty default implementation
};

class Derived : Abstract {
public:
    virtual void foo();
};

더 복잡한 기본 구현은 별도의 소스 파일로 이동합니다.


답변

ISO C ++ 표준은 순수 가상이 아닌 클래스의 모든 가상 메서드를 정의해야한다고 지정합니다.

간단히 말해서 규칙은 다음과 같습니다.
파생 클래스가 Base 클래스 가상 메서드를 재정의하면 정의도 제공해야합니다. 그렇지 않으면 Base 클래스가 해당 메서드의 정의를 제공해야합니다.

코드 예제의 위 규칙에 따라 virtual void bar();Base 클래스의 정의가 필요합니다.

참고:

C ++ 03 표준 : 10.3 가상 함수 [class.virtual]

클래스에서 선언 된 가상 함수는 정의되거나 해당 클래스에서 순수 (10.4)로 선언되거나 둘 다로 선언됩니다. 그러나 진단은 필요하지 않습니다 (3.2).

따라서 함수를 순수 가상으로 만들거나 정의를 제공해야합니다.

GCC의 자주 묻는 질문 doccuments뿐만 아니라 그것을 :

ISO C ++ 표준은 순수 가상이 아닌 클래스의 모든 가상 메서드를 정의해야하지만이 규칙 위반에 대한 진단은 필요하지 않음을 지정합니다 [class.virtual]/8. 이 가정을 기반으로 GCC는 암시 적으로 정의 된 생성자, 할당 연산자, 소멸자 및 첫 번째 비 인라인 메서드를 정의하는 번역 단위의 클래스 가상 테이블 만 내 보냅니다.

따라서이 특정 메서드를 정의하지 않으면 링커가 관련성이없는 기호에 대한 정의가 부족하다고 불평 할 수 있습니다. 안타깝게도이 오류 메시지를 개선하려면 링커를 변경해야 할 수 있으며 항상 그렇게 할 수있는 것은 아닙니다.

해결책은 순수하지 않은 모든 가상 메소드가 정의되도록하는 것입니다. 소멸자는 pure-virtual로 선언 된 경우에도 정의되어야합니다 [class.dtor]/7.


답변

예, 괜찮습니다 … 추상 기본 클래스에서 파생 된 클래스를 인스턴스화하려면 순수한 가상 함수 만 구현하면됩니다.


답변

예, Derived 클래스가 부모 클래스에서 Pure Virtual 인 함수를 덮어 써야한다는 것이 맞습니다. 순수 가상 함수를 가진 부모 클래스는 자식 클래스가 순수 가상 함수의 자체 본문을 제공해야하기 때문에 추상 클래스 라고만합니다.

일반 가상 기능의 경우 :-일부 하위 클래스에 해당 기능이있을 수 있지만 일부는 없을 수 있으므로 추가로 재정의 할 필요가 없습니다.

가상 함수 메커니즘의 주된 목적은 순수 가상 함수 (Abstract Class)의 주 목적이 자신의 바디와 동일한 이름의 함수를 가져야하는 것이 든간에 런타임 다형성입니다.