WinCNT

다중 상속과 RTTI(Runtime Type Information) 본문

게임 프로그래밍(학습 내용 정리)/C++

다중 상속과 RTTI(Runtime Type Information)

WinCNT_SSS 2021. 12. 17. 14:18

Has a이냐 Is a이냐...

 

다중 상속

장점

포함으로도 다중 상속과 같은 기능은 할 수 있다

상속이 포함보다 할 수 있는 것이 많음

계층도가 깔끔해지고 재정의도 가능하고 코드도 줄어든다

 

문제점

모호성, 위험성

새 + 말 = 페가소스

하지만 새에도 hp, 말에도 hp에도 있다면?

페가소스는 어느 hp를 가져야 하지?

 

죽음의 다이아몬드

하나의 클래스가 간접적으로 두 번 이상 동작됨

새도 동물, 말도 동물...

 

이를 해결하기 위해 virtual 키워드로 상속한다

다만, 그러면 virtual 테이블이 생겨서 관리하게 되는데 그로 인해 성능이 더 떨어질 수 있음

 

 

RTTI(Runtime Type Identification)


실행 중 객체의 타입(자료형)에 대해서 알 수 있는 매커니즘

문법적인 사용법으로는 dynamic_cast, typeid, type_info

 

다른 언어에서 좀 더 확장되면 => Reflection(C#)

클래스를 만들 거나, 클래스의 두번째 멤버 변수의 타입은 무엇인지도 알 수 있게 된다

 

dynamic_cast

캐스팅 연산자 중 하나

실행 도중의 캐스팅을 통해 타입 식별

캐스팅을 잘못해서 생기는 문제들은 어마무지하게 많다(암시적 형변환이면 더 많아질 듯) 

클래스의 포인터인 경우 dynamic_cast를 쓰면 명시적으로 형변환을 할 수 있다

 

typeid, type_info

어디에 쓸 수 있을까?

동적으로 타입을 알 수 있을 때 사용한다

예) Component 기반으로 만들 때, GetComponent 등

 

 

 

다중 상속과 RTTI는 어떤 식으로 사용되는가?

다중 상속의 예

현실 세상은 계층도가 맞는 경우가 많은데

프로그램, 특히 게임에서는 잘 안 맞는 경우가 많음

예) 몬스터를 테이밍해서 펫으로 만든다 등등

 

인터페이스 상속을 통해서 객체 설계

Movable, Renderalble 등의 속성들의 조합

 

다중 상속을 이용한 인터페이스 설계에서 RTTI를 주로 쓴다

Mk3(다중 상속)의 철학 - 한 개의 유닛을 만들기 위해서 그 속성을 다중으로 받는다

컴포넌트와 비슷하다(하지만 컴포넌트는 런타임에 어태치 디태치가 되는 무시무시한 물건)

 

트리거, 컬라이더 = 그려질 필요는 없지만 이동할 수 있는 것

다중 상속된 객체로부터 인터페이스를 분리해서 해당 리스트에 넣는다

그렇게 하면 그 속성이 있는 것에만 일괄 처리할 수 있게 된다

이러면 Update()의 처리가 매우 심플해진다

 

RTTI는 비싼데 그렇게 마구 써도 되냐?라는 반격이 있을 수 있다

(dynamic_cast도 RTTI의 하나)

 

하지만 그에 대한 반론도 있다

물론 매 프레임에 RTTI를 하면 잘못된 것(1초에 60번 불리는 등)

그러나 객체를 생성할 때 dynamic_cast 등으로 미리 분리해둬서 리스트에 넣어두면

프레임마다 부르지 않아도 되니 비용이 그리 비싸지 않다

 

객체 설계는 하기 나름

디자인 패턴도 따지고 보면 많은 설계 중 자주 쓰거나 유용한 것들이 굳어진 것

예) 싱글톤, 옵저버, 팩토리 등등

 

중요한 것은 정합성, 그리고 합당한 이유

  • 서브타입 다형성이 if를 줄일 수 있을까?
  • 다중 상속을 무서워하는 프로그래머
  • OPP 무용론, 상속 무용론
    • 기획이 바뀌면 설계가 뒤집어지는 경우가 왕왕 있다

 

SSS

'게임 프로그래밍(학습 내용 정리) > C++' 카테고리의 다른 글

예외 처리(Exception Handling)  (0) 2021.12.29
템플릿(Template)  (0) 2021.12.23
다형성(Subtype Polymorphism)  (0) 2021.12.16
상속  (0) 2021.12.14
동적 메모리 할당, 복사 생성자  (0) 2021.12.10