본문 바로가기
C++

#4. cast, dynamic_cast, RTTI, friend 클래스

by imagineer_jinny 2022. 2. 19.

 

  • const_cast
    • 클래스에서 const, volatile 및 _unaligned 특성 제거
    • const 떼주는 것

 

  • static_cast
    • 명시적 형 변환을 위한 캐스트 연산자

  • 컴파일과 런타임 차이
    • 빌드 : 소스코드 여러개를 하나로 묶는 것
    • 컴파일: 하나로 묶은 빌드 파일을 기계어로 바꿔 주는 것
    • 디버깅: 빌드. 한줄 씩 실행 하는 것
    • 런타임: 메인 들어온 이후부터

 

  • dynamic_cast
    • class의 상속 관계에서 형변환을 프로그래머가 올바르게 하도록 도와주는 기능 제공
    • RTTI(Run Time Type Information)을 지원
    • RTTI는 런타임에서 클래스의 type_info를 보고 해당 클래스가 올바른 type의 형태인지 아닌지 판단하게 해줌
    • 사용 조건
      • virtual function을 사용해야 함
      • virtual function은 오버라이딩을 통해 '다형성'을 구축
      • 왜?
        • RTTI의 type_info 때문
        • 가상함수 테이블에 포인터가 가리키는 객체 정보가 들어감
      • 작동 원리
        • virtual function을 사용하면 해당 클래스에는 v-table(가상 함수 테이블)이 생성됨
        • 이 v-table에는 override된 자식 클래스의 함수를 가르칠 수 있는 주소값이 들어있는데 이 v-table에 클래스의 type_info 정보가 들어가게 됨
        • v-table을 뒤져서 어떤게 자식인지 실행 도중에 판단하기 때문에 시간이 아주 오래 걸림
        • static_cast의 경우 안되면 에러가 나거나 강제로 바뀜. 실행 조차 안됨.
        • 반면 dynamic_cast는 성공, 실패 여부 넘겨줘서 에러 처리를 가능하게 하지만 성공/ 실패 가늠 과정에서 RTTI는 자원을 먹기 때문에 퍼포먼스 측면에서 static_cast 보다 떨어짐
      • 왜 써?
        • 성공/실패 여부 모를때
        • 왜 몰라?
          • 상속 관계를 복잡하게 하다 보면 다중 상속 문제(부모가 여러개)가 생김
          • 이 때 사람이 체크하기 힘들 수도 있음.
          • 그래서 캐스팅 되면 실행, 안되면 실행을 하지 않는 것임. 캐스팅 알고 하기 힘드니까 에러 처리 하는 것임. 이 과정에서 성능이 떨어지는 것이고 성능이 안중요한 곳에서 dynamic_cast를 씀
          • 게임에서는 성능이 제일 중요하기 때문에 애초에 상속을 복잡하게 하지 않으려고 함. 그래서 디자인 패턴이 생김

 

위의 왼쪽 코드는 virtual 함수를 안붙여서 포인터가 런타임 중에 자기가 누군지 모름. 즉 RTTI 정보를 가지지 않게 되고

오른쪽 코드는 virtual 함수를 붙여줌으로써 RTTI를 통해 자기 자신이 누군지 알게 됨

 

이건 자식 포인터로 부모를 가리키도록 하기 때문에 실패하면서 nullptr 반환

 

이 두개는 성공 케이스

왼쪽은 pBlog를 Tistory*포인터로 dynamic cast해서 넣었을 때 pBlog가 자식 가리키는 걸 아니까 자식 포인터가 자식 가리킨다 이거 괜찮다! 라고 판단을 해서 nullptr 안보낸다는 결과를 내뱉고

왼쪽은 그냥 사람이 봐도 부모가 자식 가리키는거네 그냥 static_cast 써야지 해서 잘 되는 것

 

 

  •  reinterpret_cast
    • 타입이니 뭐니 하는 것을 따지지 않고 무조건적으로 변환해버림
    • reinterpret : 다시 해석하다, 새로 해석하다
    • 대단히 위험한 방법으로 안전하다는 보장이 없다
    • 잘 안씀

 

  • friend 클래스란?
    • friend 클래스는 friend로 선언된 다른 클래스의  private 및 protected 멤버에 접근 가능
    • 특정 상황에서 클래스 내에 접근하지 못하도록 private 제한을 두었는데, 필요의 경우 해당 클래스나 함수에서 접근 가능하도록 하는 것이 friend 클래스 및 함수
    • 사용법: friend 키워드 사용하여 클래스나 함수 명시

Firend1에 Friend2가 들어오는 것을 허용해준다

 

  • friend 키워드는 단방향임. 양쪽으로 하려면 양쪽 다 써줘야 함

 

 

 

  • friend 함수
    • friend 클래스와 마찬가지로 private 및 protected 멤버에 접근할 수 있는 권한 부여 가능
    • friend 기능을 클래스 단위가 아닌 멤버 함수 단위로 지정해주는 것

 

 set_name 이라는 함수에서 Friend1 클래스의 private으로 지정되어 있는 이름만 가져다 쓰고 싶은데 쓸 수 없을 때,

그렇다고 Friend1 클래스 안에 있는 private string name을 public으로 바꾸기는 싫을 때

set_name 앞에 friend를 붙여 friend 함수를 만들어 주기!

 

 

  • Composition과 Aggregation

 

  • template

댓글