전체 코드

🚀 1. 개요

C++11에서 도입된 overridefinal 키워드는 가상 함수(virtual function)의 오버라이딩(재정의)과 관련된 중요한 기능을 제공합니다.

override: 부모 클래스의 가상 함수올바르게 재정의했는지 확인하는 키워드.
final: 특정 함수나 클래스를 더 이상 재정의(오버라이딩)하거나 상속할 수 없게 만드는 키워드.

이 문서에서는 overridefinal의 필요성, 사용법을 예제 코드와 함께 상세히 분석하겠습니다.


📂 2. 코드 분석

🎯 기본 클래스 Creature

class Creature
{
public:
    virtual void Attack()
    {
        cout << "Creature!" << endl;
    }
};

Creature 클래스

  • Creature기본 클래스(Base Class)입니다.
  • 가상 함수 Attack
    • virtual 키워드가 붙어 있어 자식 클래스에서 오버라이딩 가능.
    • Attack이 호출되면 "Creature!"를 출력합니다.

🎯 오버라이딩 예제: Player 클래스

class Player : public Creature
{
public:
    virtual void Attack() override
    {
        cout << "Player!" << endl;
    }
};

Player 클래스 (파생 클래스)

  • PlayerCreature상속받아 새로운 기능을 추가합니다.
  • override 키워드 사용
    • override를 붙이면 부모 클래스의 가상 함수를 올바르게 재정의했는지 컴파일러가 확인합니다.
    • 타이핑 실수 또는 부모 함수의 시그니처 변경을 방지하는 역할을 합니다.
  • Attack 함수 호출 시 "Player!"가 출력됩니다.

🎯 더 깊은 상속 예제: Knight 클래스

class Knight : public Player
{
public:
    virtual void Attack() override
    {
        cout << "Knight!" << endl;
    }
};

Knight 클래스 (파생 클래스)

  • KnightPlayer 클래스를 상속받아 기능을 추가.
  • override를 사용하여 Attack을 재정의.
  • Attack 함수 호출 시 "Knight!"가 출력됩니다.

🎯 오버라이딩을 막는 final 키워드

class Knight : public Player
{
public:
    virtual void Attack() override final
    {
        cout << "Knight!" << endl;
    }
};

final 키워드 추가

  • override final을 사용하면 자식 클래스에서 Attack을 더 이상 오버라이딩할 수 없음.
  • 만약 final이 붙은 Attack을 오버라이딩하려 하면 컴파일 에러 발생.
class SuperKnight : public Knight
{
public:
    // ERROR! 'Attack' is final in 'Knight'
    virtual void Attack() override // ❌ 컴파일 에러 발생
    {
        cout << "SuperKnight!" << endl;
    }
};

💡 final을 사용하면 예상치 못한 함수 오버라이딩을 방지하고 코드의 안정성을 높일 수 있음.


🎯 main() 함수 분석

int main()
{
    Player* player = new Knight();
    player->Attack();
    return 0;
}

다형성(Polymorphism) 활용

  • Player* player = new Knight();:
    • Player 포인터가 Knight 객체를 가리킴.
    • 런타임 다형성(Run-time Polymorphism) 구현.
  • player->Attack();
    • 가상 함수 테이블(vtable)을 통해 KnightAttack이 실행됨.
    • 출력 결과:
      Knight!
    • Knight 클래스의 Attack()이 최종적으로 호출됨.

📌 3. overridefinal 비교

기능overridefinal
용도올바른 오버라이딩인지 검증오버라이딩을 차단
사용 위치가상 함수(virtual function)가상 함수 또는 클래스
컴파일 에러 발생 여부잘못된 오버라이딩 시 컴파일 에러오버라이딩을 시도하면 컴파일 에러
가독성 향상부모 함수와의 관계를 명확히 함더 이상 변경되지 않는 함수임을 명확히 표현

override재정의(Overriding)한 함수가 부모의 가상 함수와 정확히 일치하는지 검증.
final특정 함수(또는 클래스)의 상속/오버라이딩을 금지하여 코드 안정성을 높임.


📌 4. final 클래스 예제

class FinalClass final
{
public:
    void SayHello()
    {
        cout << "Hello from FinalClass!" << endl;
    }
};

// ERROR! FinalClass를 상속할 수 없음
class Derived : public FinalClass
{
};

클래스 자체를 상속 금지

  • FinalClassfinal이므로 더 이상 상속할 수 없음.
  • Derived 클래스를 정의하려 하면 컴파일 에러 발생.

📌 5. 추가 학습

🔹 const를 사용한 함수 오버로딩

class Player
{
public:
    virtual void Attack() { cout << "Player!" << endl; }
};

class Knight : public Player
{
public:
    virtual void Attack() const  // ❌ 부모 함수와 시그니처가 다름
    {
        cout << "Knight!" << endl;
    }
};

const를 붙이면 부모 클래스의 함수와 다른 함수로 간주됨
함수 시그니처가 다르므로 override가 적용되지 않음
오버라이딩을 원하면 부모 함수에도 const를 추가해야 함


profile
李家네_공부방

0개의 댓글