'override'키워드는 재정의 된 가상 메소드를 점검하는 것입니까?


226

지금까지 내가 이해의 도입 override(11) C ++의 키워드는 아무것도 확실히 구현되는 기능이되는지 확인하기 위해 더 많은 검사보다하지 override의 ING virtual기본 클래스의 기능.

그게 다야?



13
그러나 이중 점검은 아닙니다. 유일한 검사입니다.
Nikos C.

13
재정의는 키워드가 아니며 문법적인 설탕입니다. int override = 42; // OK
KAlO2

2
또한 선언 된 함수가 재정의
됨을

5
그래서, 어 .. C ++ 11이 언제 내 지역 4 년에 이런 것들을 가르치기 시작할 정도로 표준이됩니까? 그들은 언제 알 수 있습니까?!
Cinch

답변:


263

그 아이디어입니다. 요점은 당신이 의미하는 바에 대해 명시 적이므로 그렇지 않으면 자동 오류를 진단 할 수 있다는 것입니다.

struct Base
{
    virtual int foo() const;
};

struct Derived : Base
{
    virtual int foo()   // whoops!
    {
       // ...
    }
};

위의 코드는 컴파일되지만 의도 한 것이 아닙니다 (누락 된 참고 const). 대신이라고 말하면 virtual int foo() override실제로 함수가 무시하지 않는 컴파일러 오류가 발생합니다.


74
+1 : 불행히도 사람들이 새로운 override기능이 이것을 고치라고 제안 할 때 약간의 청어입니다 . 당신은 당신이 쓸 기억해야하는 것처럼, 그것을 사용하는 기억해야 const)
궤도의 밝기 경주를

방금 explicit클래스 정의가 C ++ 11로 만들지 않았다는 것을 깨달았습니다 . 허.
aschepler

1
@aschepler 그리고 explicit클래스 정의는 무엇을할까요? 그것에 대해 전혀 들어 본 적이 없습니다.
Christian Rau

18
@LightnessRacesinOrbit : 그렇습니다. 그러나 일반적인 규칙을 기억하는 것 (모욕 override할 때 쓸 수없는 글쓰기 )은 모퉁이 사례를 기억하는 것보다 더 가능성이 높습니다. 즉, 다른 프로토 타입의 기능을 복사하는 데에는 일반성이 없으며 대신에 누락 const또는 쓰기 와 같은 불규칙성이있을뿐입니다 .charint
legend2k

1
이 답변 에서는 override지정자 의 최상의 사용 사례 인 @Light 가 언급되어 있는데, 이는 즉각적인 것보다 미래입니다. 대답은 계속 제안 으로 하는 방법. 미래에 서명을 실수로 변경하면 그 유용성이 시작됩니다.overridevirtual
iammilind

35

Wikipedia 인용문 :

특수 식별자 무시는 컴파일러가 기본 클래스를 검사하여이 정확한 서명을 가진 가상 함수가 있는지 확인합니다. 그리고 없으면 컴파일러에서 오류가 발생합니다.

http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final

편집 (약간 답변을 개선하려고 시도) :

메소드를 "재정의"로 선언한다는 것은 해당 메소드 기본 클래스에서 (가상) 메소드를 다시 작성 한다는 의미입니다 . 재정의 메소드는 재 작성하려는 메소드와 동일한 서명을 가져야합니다 (적어도 입력 매개 변수의 경우).

왜 이것이 필요한가요? 다음과 같은 두 가지 일반적인 오류가 방지됩니다.

  1. 새 메소드에서 유형을 잘못 입력합니다. 컴파일러는 이전 메소드를 작성하려고한다는 것을 인식하지 않고 단순히 클래스에 새 메소드로 추가합니다. 문제는 이전 방법이 여전히 존재하고 새로운 방법은 과부하로 추가된다는 것입니다. 이 경우 이전 메소드에 대한 모든 호출은 동작의 변경없이 (재 작성의 목적이었던) 이전과 같이 작동합니다.

  2. 수퍼 클래스에서 메소드를 "가상"으로 선언하는 것을 잊었지만 여전히 서브 클래스에서 다시 작성하려고 시도합니다. 이것이 명백하게 받아 들여질 것이지만, 동작은 의도 한대로 정확하지 않을 것입니다 : 메소드가 가상이 아니기 때문에, 슈퍼 클래스에 대한 포인터를 통한 액세스는 새로운 (서브 클래스) 메소드 대신에 오래된 (수퍼 클래스) 메소드 호출을 종료합니다.

"재정의"를 추가하면이를 명확하게 명확하게 할 수 있습니다.이를 통해 컴파일러는 다음 세 가지를 기대하고 있습니다.

  1. 수퍼 클래스에 같은 이름의 메소드가 있습니다
  2. 슈퍼 클래스에서이 메소드는 "가상"으로 선언됩니다 (즉, 다시 쓰도록 의도 됨)
  3. 수퍼 클래스의 메소드는 서브 클래스의 메소드 (재 작성 메소드)와 동일한 (입력 *) 서명을 갖습니다.

이 중 하나라도 거짓이면 오류가 발생합니다.

* 참고 : 출력 매개 변수가 다른 경우도 있지만 관련 유형이 다릅니다. 관심이있는 경우 공변량 및 반 변량 변환에 대해 읽으십시오.


31

발견 된 " override "는 선택적 매개 변수 추가와 같은 기본 클래스 가상 메소드 서명을 업데이트했지만 파생 클래스 메소드 서명을 업데이트하는 것을 잊었을 때 유용합니다. 이 경우 기본 클래스와 파생 클래스 간의 메서드는 더 이상 다형성 관계가 아닙니다. 재정의 선언이 없으면 이런 종류의 버그를 찾기가 어렵습니다.


1
+1. override그러한 문제를 발견하는 좋은 방법 이지만 , 단위 테스트 범위가 좋으면 도움이 될 것입니다.
환멸

1
이것이 바로 새로운 지정자에 대해 매우 흥분되는 이유입니다. 유일한 문제점은 기본 클래스의 변경으로 인한 오류를 방지하기 위해이 기능이 이미 적용되어 있어야한다는 것입니다. ;-)
Wolf


2

C ++ 17 표준 초안

C ++ 17 N4659 표준 초안override 에 대한 모든 적중을 검토 한 후 식별자에 대한 유일한 참조 는 다음과 같습니다.override

5 가상 함수가 virt-specifier 재정의로 표시되고 기본 클래스의 멤버 함수를 재정의하지 않으면 프로그램이 잘못 구성됩니다. [ 예:

struct B {
  virtual void f(int);
};

struct D : B {
  virtual void f(long) override; // error: wrong signature overriding B::f
  virtual void f(int) override;  // OK
}

— 최종 예]

따라서 잘못된 프로그램을 폭파시키는 것이 실제로 유일한 효과라고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.