2009-05-07 2 views

답변

7

함수는 파생 클래스가 다른 방식으로 함수를 구현할 경우에만 가상 일 필요가 있습니다. 예를 들어

: 결과

class Base { 
public: 
    void setI (int i) // No need for it to be virtual 
    { 
    m_i = i; 
    } 

    virtual ~Base() {}   // Almost always a good idea 

    virtual bool isDerived1() // Is overridden - so make it virtual 
    { 
    return false; 
    } 

private: 
    int m_i; 
}; 

class Derived1 : public Base { 
public: 
    virtual ~Derived() {} 

    virtual bool isDerived1() // Is overridden - so make it virtual 
    { 
    return true; 
    } 
}; 

, 당신이 당신이 행동을 요구하는 것을 발견 할 때까지 당신이 그것을 무시하려는 또는 사전에 알고하지 않는 가상 아무것도 가지고 있지의 측면 에러 것이다. 유일한 예외는 소멸자입니다. 거의 인 경우 항상 기본 클래스에서 가상으로 유지하려는 경우입니다.

+1

적어도 하나의 메서드가 클래스에서 가상 일 때 가상 소멸자가 있어야합니다. – stefanB

0

인터페이스 기능은 일반적으로 가상해야합니다. 고정 된 기능을 제공하는 함수는 가져서는 안됩니다.

2

가상화하려는 가상 사물 만 만드는 경향이 있습니다. 재정의하고자하는 것에 대한 초기 가정이 잘못되었다고 판단되면 나는 다시 기본 클래스를 변경합니다.

아, 상속 된 무언가를 작업하고 있다면 분명히 항상 소멸자를 가상으로 만듭니다.

0

왜 실제로 그것을 무시할 때까지 가상으로 선언할까요? 나는 그것이 확실한 것인지 아닌지에 대한 질문이 아니라고 생각합니다. 사실을 따르십시오 : 그것은 어딘가에서 오버 라이딩됩니까? 아니? 그렇다면 그것이 가상이 아니어야합니다.

+0

이렇게하면 하나의 하위 클래스를 변경 (이전에 재정의하지 않은 메서드를 재정의)하려는 경우 기본 클래스를 변경하여 (가상 메서드를 만들기 위해) 참조하는 모든 코드를 다시 컴파일해야한다는 상황이 발생합니다 기본 클래스 일부 프로젝트에서는 기본 클래스의 취약성이 문제가되지 않지만 다른 클래스에서는 취약합니다. 빌드 프로세스 및 기본 클래스의 인터페이스 게시 여부에 따라 다릅니다. –

+1

그래서 IMO 메소드는 가상 클래스가되어야한다. 서브 클래스가 그것들을 오버라이드 할 수 있다면 (그리고 런타임 다형성이 지원된다.) 실제로는 그렇지 않다. –

1

당신이 기본 클래스 (당신이 누군가가 클래스를 파생 확실하다) 당신은 다음과 같은 일을 할 수 만드는 경우 :

  • 만들기 소멸자 가상 (기본 클래스에 대한 필수)를
  • 이 방법을 정의를하는 파생 된 가상의 것입니다 있어야합니다.
  • 가상이 아닌 (또는 이 아니어야 함) 메소드를 정의하십시오.
  • 함수가 파생 된 클래스 전용이고 기본 클래스가 아닌 경우 을 보호 대상으로 표시합니다.
1

컴파일러는 기본 유형의 포인터가 가상 함수를 호출 할 때 어떤 실제 코드가 실행되는지 알 수 없습니다. 실행될 실제 코드 조각은 실행시에 기본 클래스 포인터가 가리키는 객체에 따라 평가되어야합니다. 따라서 함수가 상속 된 클래스에서 재정의되지 않으면 가상 함수를 사용하지 마십시오.

TLDR 버전 : "가상 함수 집합과 상속되지 않을 가상 함수 집합이 있어야합니다." 가상 함수는 런타임에 성능 저하를 유발하기 때문입니다.

4

의도 한 기능을 오버라이드 가상으로 디자인해야합니다. 가상을 만드는 것은 유지 보수와 성능면에서 자유롭지 않습니다 (유지 보수가 훨씬 더 큰 문제 인 IMHO입니다).

일단 메서드가 가상이면이 메서드를 사용하는 코드를 추론하기가 더 어려워집니다.하나의 메소드 호출이 무엇을 할 것인가를 고려하는 대신 N 메소드 호출이 그 시나리오에서 무엇을 할 것인지를 고려해야 만합니다. N은 해당 메서드를 재정의하는 하위 클래스 수를 나타냅니다.

이 규칙의 예외는 소멸자입니다. 파생 된 클래스에서 가상해야합니다. 할당 해제 중에 적절한 소멸자가 호출되도록 보장하는 유일한 방법입니다.

4

가상 인터페이스가 아닌 idiom (C++ Coding Standards item 39)은 기본 클래스가 비가 상 인터페이스 메서드를 가져야하며 기본 클래스가 불변 조건을 보장 할 수 있고 기본 클래스의 사용자 지정을위한 비공개 가상 메서드가 있어야한다고 말합니다 파생 클래스에 의한 동작. 비 가상 인터페이스 메서드는 가상 메서드를 호출하여 재정의 할 수있는 동작을 제공합니다.

+0

소스를 여기에 추가하는 것을 고려하십시오. "C++ 코딩 표준, 101 규칙, 지침 및 모범 사례, Herb Sutter 및 Andrej Alexandrescu"를 참조하십시오. 그러나 C++에는 공식 코딩 표준이 없습니다. – patrik

관련 문제