본문 바로가기

C++

[TIL 25장] 캐스팅(업캐스팅, 다운캐스팅), 캐스팅 연산자

오늘의 TIL 목차 (22. 09. 07)

 

  • 캐스팅 (업 캐스팅, 다운 캐스팅)
  • 캐스팅 연산자 (C++ 형 변환)

캐스팅


[ 캐스팅 ]

: 형 변환, 그룹핑 목적으로 상속 관계의 서로 다른 클래스를 같은 타입으로 묶을 때 업캐스팅/다운캐스팅이 주로 일어남 

 

[ 업캐스팅 & 다운 캐스팅 ]
// 부모 CParents, 자식 CChild 클래스가 존재할 때

* 대입 연산자(=)를 기준으로 우항이 좌항으로 대입되면서 좌항에 맞춰 캐스팅이 발생한다. 
	- 대입 연산자는 좌항과 우항의 자료형이 동일해야 하기 때문
* 상속 관계에서의 캐스팅은 포인터나, 레퍼런스로만 캐스팅이 이뤄진다.
	- 캐스팅 당하는 객체가 실제로 변하지 않고, 포인터와 레퍼런스로 보는 관점만 달리지는 것
* 기본적으로 자식이 부모 객체를 가리키는 업 캐스팅은 지원되지 않는다.
	- 업 캐스팅 된 포인터를 명시적 형 변환으로 다운 캐스팅 하는 것은 가능
* 가리키는 객체 안에서 자신의 포인터 타입 부분만 식별할 수 있다.

[ 업캐스팅 ]
: 자식 객체를 부모 타입으로 해석하는 것
CParents* pParents = new CChild; // CChild 기본 생성자 타입으로 힙 메모리에 객체 생성
=> CParents* pParents = (CParents*) (new CChild); 로 자식이 부모 타입으로 묵시적 업 캐스팅

[ 다운 캐스팅 ]
: 동일한 타입의 포인터가 동일한 타입을 가리키는 것
class CParents {
public:
	void Print() { cout << "hello" << endl; }
}
class CChild : public CParents {
public:
	void Render() { cout << "Home" << endl; }
}

CParents* pParents = new CChild; 로 업캐스팅 시
pParents는 CChild의 멤버 중 상속받은 CParents 부분만 식별함 ( CChild의 Render() 호출 불가 )
그래서 일시적으로 CParents타입의 pParents를 CChild로 다운캐스팅 하여 식별할 수 있도록 해줌
static_cast<CChild*>(pParents)->Render(); // CChild의 Render() 호출 가능해짐
=> 포인터, 또는 레퍼런스로만 캐스팅 가능, 즉 pParents 자체는 바뀌지 않고
=> 포인터를 통해 바라보는(식별할 수 있는) 범위만 달라짐 - 해당 라인에서만 적용됨

* CChild pChild = new CParents; 로 다운 캐스팅 불가
=> 우항에서 좌항으로 대입이 되는데 부모 CParents는 자식이 누군지 모름
=> 명시적 캐스팅 시 컴파일에선 오류가 안 뜨나 런타임 시 오류 발생

※ 클래스 특징인 다형성을 위해 캐스팅이 주로 발생함 ( 그룹핑, 오버라이딩 때문 )

 

■ 기능 / 주의

  •  

■ 예시

 

캐스팅 연산자


[ 캐스팅 연산자 ]

: C++ 이후에 지원되는 캐스팅 연산자 ( 프로그래머가 맘대로 형 변환하는 것의 위험성을 방지 목적 )

[ C++에서 지원하는 캐스팅 연산자 ]
: 캐스팅연산자<자료형>(변수/객체);

@. static_cast<>()
:

@. dynamic_cast<>()
: 런타임 시점에 형 변환해주는 캐스팅
- 반드시 상속 관계인 (virtual이 하나라도 있어야 함) 다형적인 포인터만 사용 가능한 연산자
- 동적인 시점에 안전성 검사를 하기 때문에 다른 캐스팅보다 속도가 느림
- 안전하지 않은 다운 캐스팅을 시도할 경우 nullptr을 반환

@. const_cast<>()
: 포인터 및 레퍼런스 형만 형 변환이 가능한 연산자, const의 성향을 제거하는 캐스팅

@. reinterpret_cast<>()
: const 포인터를 제외한 모든 포인터 형 변환 허용