[Effective C++] 05. 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자

2025. 11. 28. 18:30·C++/[서적] Effective C++

작동 방식

(1) 생성자

class Base {
public:
    Base() {
        Initialize(); // Base::Initialize()가 호출됨
    }
    virtual void Initialize() {
        UE_LOG(LogTemp, Log, TEXT("Base Init"));
    }
};

class Derived : public Base {
public:
    Derived() : Base() {
        // Base 생성자 실행 시점에는 아직 Derived 객체가 완성되지 않음
    }
    virtual void Initialize() override {
        UE_LOG(LogTemp, Log, TEXT("Derived Init"));
        // 이 함수는 호출되지 않음!
    }
};

기본 클래스인 Base 의 생성자에서 가상 함수를 호출하고 있다. 생성자의 호출 순서는 기본 클래스가 먼저 호출된 이후 파생 클래스의 생성자가 호출된다. 따라서 기본 클래스의 생성자가 호출될 타이밍에는 파생 클래스가 초기화되지 않은 시점이기 때문에 Initialize는 기본 클래스의 정의를 따라가게 된다. 


(2) 소멸자

class Base {
public:
    virtual ~Base() {
        Cleanup(); // 개발자는 파생 클래스 버전이 호출될 것으로 기대
    }
    virtual void Cleanup() {
        UE_LOG(LogTemp, Log, TEXT("Base Cleanup"));
    }
};

class Derived : public Base {
    UTexture2D* ImportantTexture;
public:
    virtual ~Derived() {
        // ImportantTexture는 아직 유효
    }
    
    virtual void Cleanup() override {
        UE_LOG(LogTemp, Log, TEXT("Derived Cleanup"));
        if (ImportantTexture) {
            ImportantTexture->RemoveFromRoot(); // 실행 안 됨!
        }
    }
};

소멸자의 호출 순서는 파생 클래스인 Derived의 소멸자가 먼저 호출된 이후 Base의 소멸자가 호출된다. Base의 소멸자에서 호출하는 가상 함수인 Cleanup이 Derived의 Cleanup을 호출할 것으로 기대하여 위처럼 코드를 작성하게 된다면, ImportantTexture가 제대로 정리되지 않을 수 있다.

 


 

해결 방법

절대로 생성자, 소멸자에서는 가상 함수를 호출하지 말것.

 

 기존에 호출하던 기본 클래스의 가상 함수를 비가상 함수로 변환한 후, 생성자의 매개변수로 파생 클래스의 정보를 넘겨받아 초기화하도록 구현하는 것이 좋다.

// Base.h
class Base {
public:
    Base(const string& classInfo)
    {
        Initialize(classInfo);
    };
    
    void Initialize(const string& classInfo);
};

// Derived.h
class Derived : public Base {
public:
    Derived()
    : Base(classInfo)
    { };
};

'C++ > [서적] Effective C++' 카테고리의 다른 글

[Effective C++] 07. operator= 에서는 자기대입에 대한 처리가 빠지지 않도록 하자  (0) 2025.11.28
[Effective C++] 06. 대입 연산자는 *this의 참조자를 반환하게 하자  (0) 2025.11.28
[Effective C++] 04. 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자  (0) 2025.11.28
[Effective C++] 03. C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자  (0) 2025.11.28
[Effective C++] 02. 객체를 사용하기 전에 반드시 그 객체를 초기화하자  (0) 2025.11.28
'C++/[서적] Effective C++' 카테고리의 다른 글
  • [Effective C++] 07. operator= 에서는 자기대입에 대한 처리가 빠지지 않도록 하자
  • [Effective C++] 06. 대입 연산자는 *this의 참조자를 반환하게 하자
  • [Effective C++] 04. 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자
  • [Effective C++] 03. C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자
Meoyoung's Development Logs
Meoyoung's Development Logs
내가 보려고 만든 블로그
  • Meoyoung's Development Logs
    이게뭐영
    Meoyoung's Development Logs
  • 전체
    오늘
    어제
    • 분류 전체보기 (287) N
      • Unreal Engine 프로젝트 (36) N
        • 더 퍼스트 버서커 : 카잔 (16)
        • VR 공포게임 (13)
        • Paper-ZD (7) N
      • 언리얼 엔진 (70)
        • GAS (12)
        • 트러블슈팅 (27)
        • 캐릭터 (2)
        • VR (1)
        • Lighting (2)
        • 멀티스레드 (2)
        • Lyra (0)
      • C++ (31)
        • 문법 정리 (8)
        • [서적] Fundamental C++ 프로그래밍 .. (5)
        • [서적] 이것이 C++이다 (11)
        • [서적] Effective C++ (7)
      • 게임잼 (3)
      • 강의 (36)
        • [강의] 이득우의 언리얼 프로그래밍 Part1 (13)
        • [강의] 이득우의 언리얼 프로그래밍 Part2 (2)
        • [강의] 이득우의 언리얼 프로그래밍 Part3 (12)
        • [강의] 소울라이크 개발 A-Z (4)
        • [강의] Udemy-2D (5)
      • C# (1)
        • [서적] 이것이 C#이다 (1)
      • 코딩테스트 (26)
        • 프로그래머스 (6)
        • 알고리듬 (13)
        • 자료구조 (7)
      • 컴퓨터 과학 (27)
        • 운영체제 (11)
        • 데이터베이스 (0)
        • 디자인패턴 (0)
        • 자료구조 (5)
        • 네트워크 (0)
        • 컴퓨터구조 (11)
      • 면접준비 (0)
        • C++ (0)
        • 운영체제 (0)
        • 자료구조 (0)
      • 기타 (48)
        • [팀프로젝트] The Fourth Descenda.. (5)
        • GetOutOf (15)
        • [개인프로젝트] FPS 구현 맛보기 (5)
        • [서적] 인생 언리얼5 (4)
        • 스파르타코딩클럽 (15)
        • 객체지향프로그래밍 (2)
        • 컴퓨터회로 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    셸정렬
    선택정렬
    자료구조
    경북게임잼
    게임개발
    삽입정렬
    참가후기
    버블정렬
    알고리즘
    게임잼
    쉘정렬
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Meoyoung's Development Logs
[Effective C++] 05. 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자
상단으로

티스토리툴바