`override` 지정자
override 지정자 (C++11부터)
가상 함수를 오버라이드할 때, 시그니처를 살짝 잘못 쓰면 조용히 새 가상 함수가 생겨버려요. override 지정자는 바로 여기서 방패 역할을 해요. 멤버 함수 선언이나 정의에 override를 붙이면, "이 함수는 반드시 가상 함수이고 기반 클래스의 가상 함수를 오버라이드해야 한다"고 컴파일러에게 못박는 거예요. 그 조건이 어긋나면 프로그램은 ill-formed(컴파일 타임 에러)가 돼요.
override는 멤버 함수의 declarator 뒤에서 쓰일 때만 특별한 의미를 갖는 **특별한 의미의 식별자(identifier with a special meaning)**예요. 그 외에는 예약 키워드가 아니에요. 그래서 함수 이름이나 변수 이름으로도 자유롭게 쓸 수 있어요.
출처: cppreference
본문
문법(Syntax)
override는 사용한다면 클래스 정의 안의 멤버 함수 선언이나 멤버 함수 정의 문법에서 declarator 바로 뒤에 나타나요.
declarator virt-specifier-seq (선택) pure-specifier (선택) |
(1) |
declarator virt-specifier-seq (선택) function-body |
(2) |
-
멤버 함수 선언에서,
override는 declarator 바로 뒤, 그리고 pure-specifier(쓰는 경우) 앞의virt-specifier-seq에 나타날 수 있어요. -
클래스 정의 안의 멤버 함수 정의에서,
override는 declarator 바로 뒤,function-body바로 앞의virt-specifier-seq에 나타날 수 있어요.
두 경우 모두 virt-specifier-seq은 (쓰면) override, final, final override, override final 중 하나예요.
설명(Explanation)
멤버 함수 선언이나 정의에서 override 지정자는 그 함수가 가상 함수이고 기반 클래스의 가상 함수를 오버라이드한다는 것을 보장해요. 그렇지 않으면 프로그램은 ill-formed(컴파일 타임 에러)가 돼요.
override는 멤버 함수 declarator 뒤에서 쓰일 때 특별한 의미를 갖는 식별자이지, 그 외에는 예약 키워드가 아니에요.
키워드(Keywords)
예제(Example)
override가 어떻게 오버라이드 요건을 강제하는지, 그리고 그 외의 문맥에서는 보통 식별자로 쓰이는지 보여 주는 예시예요.
#include <iostream>
struct A
{
virtual void foo();
void bar();
virtual ~A();
};
// struct A의 멤버 함수 정의:
void A::foo() { std::cout << "A::foo();\n"; }
A::~A() { std::cout << "A::~A();\n"; }
struct B : A
{
// void foo() const override; // 에러: B::foo는 A::foo를 오버라이드하지 않음
// (시그니처 불일치)
void foo() override; // OK: B::foo가 A::foo를 오버라이드함
// void bar() override; // 에러: A::bar는 가상 함수가 아님
~B() override; // OK: `override`는 소멸자 같은 가상 특수 멤버 함수에도 적용 가능
void override(); // OK, 멤버 함수 이름이지 예약 키워드가 아님
};
// struct B의 멤버 함수 정의:
void B::foo() { std::cout << "B::foo();\n"; }
B::~B() { std::cout << "B::~B();\n"; }
void B::override() { std::cout << "B::override();\n"; }
int main()
{
B b;
b.foo();
b.override(); // OK, 멤버 함수 `override()`를 호출함
int override{42}; // OK, 정수 변수를 정의함
std::cout << "override: " << override << '\n';
}
출력:
B::foo();
B::override();
override: 42
B::~B();
A::~A();
더 알아보기
final지정자(C++11): 메서드를 오버라이드할 수 없게, 또는 클래스를 파생시킬 수 없게 선언.