가상 함수는 C++의 초기부터 동적 다형성의 도구로 존재해왔습니다. 그러나 이전에는 상속 클래스에서 가상 함수 재정의의 올바름을 컴파일러가 확인할 수 있는 구문적 메커니즘이 없었습니다. C++11이 등장한 후 override 키워드는 컴파일러의 추가적인 검증 도구가 되었습니다.
override가 없으면 컴파일러는 해당 함수가 실제로 기반 클래스의 메서드를 재정의하는지 보장하지 않습니다. 서명 오류(예: 잘못된 타입 또는 const)가 발생하면 파생 클래스에서 새로운 함수가 생성되어(“가리기”) 다형성이 깨지고 디버깅이 어렵습니다.
파생 클래스에서 가상 함수를 선언할 때 override를 사용하면 컴파일러가 서명이 부모의 가상 함수와 정확히 일치하는지 확인하고 함수가 실제로 부모를 재정의하는지 체크할 수 있습니다. 그렇지 않으면 컴파일이 오류로 중단됩니다.
코드 예시:
struct Base { virtual void foo() const {} }; struct Derived : Base { void foo() const override { /* 구현 */ } };
Derived에서 void foo()를 const override 없이 작성하면 컴파일러는 오류를 발생시킵니다.
주요 특징:
'override' 키워드가 있지만 'virtual' 키워드가 없는 가상 함수를 남길 수 있는가?
네, override는 함수가 가상임을 암시합니다. override와 함께 virtual을 명시하는 것은 중복되지만 금지되지는 않습니다.
함수가 const나 ref 한정자(예: & 또는 &&)에 따라 다를 경우 오류가 발생할 수 있는가?
네, const/references에 따라 서명이 다르면 재정의가 깨집니다. 예를 들어, void foo() override는 void foo() const를 재정의하지 않으며, override 덕분에 컴파일러가 이를 식별합니다.
정적 함수나 생성자에 'override'를 적용할 수 있는가?
아니요. override는 오직 가상 함수에만 해당되며 정적 함수, 생성자, 소멸자(가상적이지 않은 경우)에는 적용할 수 없습니다.
대규모 프로젝트에서 상속 클래스에 함수의 서명에 오타가 발생해서 그 함수는 실제로 재정의되지 않지만 개발자는 그렇지 않다고 생각하며 다형성이 예상대로 작동하지 않습니다.
장점:
단점:
모든 파생 클래스에서 override를 사용하며, 테스트가 빌드 단계에서 오류를 포착합니다.
장점:
단점: