`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)
  1. 멤버 함수 선언에서, override는 declarator 바로 뒤, 그리고 pure-specifier(쓰는 경우) 앞의 virt-specifier-seq에 나타날 수 있어요.

  2. 클래스 정의 안의 멤버 함수 정의에서, 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): 메서드를 오버라이드할 수 없게, 또는 클래스를 파생시킬 수 없게 선언.