RTTI
- RTTI는 실행시간 데이터형 정보라는 뜻이다.
- 가상 함수들을 가지고 있는 클래스들에 대해서만 사용할 수 있다.
dynamic_cast 연산자
- 가능하다면 기초클래스형을 지시하는 포인터로부터 파생클래스형을 지시하는 포인터를 생성한다.
- 가능하지않다면 널포인터인 0을 리턴한다.
- 포인터가 지시하는 객체형이 무엇인지 알려 주지 않는다.
- 객체의 주소를 특정형의 포인터에 안전하게 대입할 수 있는지 알려준다.
class Grand { //가상 메서드들을 가지고 있다. };
class Sup : public Grand { ... };
class Magn : public Sup { ... };
Grand * pg = new Grand;
Grand * ps = new Sup;
Grand * pm = new Magn;
Magn * p1 = (Magn *) pm; //#1
Magn * p2 = (Magn *) pg; //#2
Sup * p3 = (Magn *) pm; //#3
- 위와 같은 상황에서 #1은 Magn포인터가 Magn형 객체를 지시해서 안전하다.
- #2는 기초클래스 객체의 주소를 파생클래스에 대입하므로 안전하지 않다.
- #3은 파생클래스 객체의 주소를 기초클래스 포인터에 대입하므로 안전하다.
- Magn는 Sup은 기초, Grand는 간접기초이기 때문에 세가지모두에 대입하여도 안전하다.
Grand* pg = new Grand();
Grand* ps = new Sup;
Grand* pm = new Magn;
Sup* pss = new Sup;
Sup* ss = dynamic_cast<Sup*>(ps); //다운캐스팅
Grand* sss = dynamic_cast<Sup*>(pss); //업캐스팅
- dynamic_cast<Type *> (pt)같은 표현은 포인터 pt에 의해 지시되는 객체(*pt)가 Type형이거나, Type형으로부터 직접, 간접적으로 파생된 객체일 경우 포인터pt를 Type *형의 포인터로 변환한다.
- 그렇지 않을경우는 널포인터인 0이된다.
dynamic_cast 참조일 때의 사용
Sup pssss;
Sup& kk = pssss;
try
{
Sup& ss = dynamic_cast<Sup&>(kk);
}
catch (bad_cast &)
{
};
- 널포인터에 해당하는 참조값이 없기에 그렇지 않을경우에 해당할 때에 bad_cast형의 예외를 발생시킨다.
- bad_cast는 typeinfo 헤더파일에 정의되어있다.
typeid연산자와 type_info 클래스
typeid(Magn) == typeid(*pg);
- pg가 Magn 객체를 지시하는 포인터면 true 아니면 false로 평가된다.
- pg가 널포인터면 프로그램은 bad_typeid 예외를 발생시킨다.
typeid(*pg).name();
- 포인터 pg가 지시하는 객체의 클래스 이름을 출력한다.
const_cast 연산자
const_cast <type_name> (expression)
- 데이터형의 다른 어떤 측면이 변경되면 에러이다.
- 즉 const, volatile이 있나 없나에 따라 달라지는것을 빼고는 type_name과 expression의 데이터형이 일치해야한다.
- 포인터나 참조의 상수성을 잠깐 제거하는데 사용한다.
High bar;
const High * pbar = & bar;
High * pb = const_cast<High *> (pbar); //맞다
const Low * pl = const_cast<const Low *> (pbar); //틀리다
- 첫번째 데이터형 변환은 *pb를 bar 개체의 값을 변경하는데 사용할 수 있는 포인터로 만든다.
static_cast 연산자
static_cast <type_name> (expression)
High bar;
Low blow;
...
High * pb = static_cast<High *> (&blow); //유효한 업캐스트
Low * pl = static_cast<Low *> (&bar); //유효한 다운캐스트
Pond * pmer = static_cast<Pond *> (&blow); //유효하지않다 (관련없는 클래스)
- type_name이 그 expression이 가지는 데이터형으로 암시적으로 변환될 수 있을때에만 유효하다.
- 형변환 능력을 가진 가장 기본적인 캐스트 연산자이다.
- 포인터 형변환이 안된다.
reinterpret_cast 연산자
reinterpret_cast <type_name> (expression)
참고 사이트 : https://docs.microsoft.com/ko-kr/cpp/cpp/dynamic-cast-operator?view=msvc-160
https://bbagwang.com/programming/cpp/c-%EC%97%90%EC%84%9C%EC%9D%98-cast/
'C++ > Basic' 카테고리의 다른 글
[C++] 출력 함수 (0) | 2021.08.12 |
---|---|
[C++] stl set (0) | 2021.08.09 |
[C++] 예외 처리 (2) | 2021.07.26 |
[C++] 내포 클래스 (0) | 2021.07.23 |
[C++] 프렌드 클래스 (0) | 2021.07.22 |