Programing/Design Pattern

dynamic_casting

Napoliano 2025. 1. 17. 16:56
728x90

 

 

 

https://www.ecourse.co.kr/courses/cpp_designpattern/lessons/virtual-function-2/#tab-201442

 

C++ Design Pattern → virtual function - ecourse

 

www.ecourse.co.kr

 

class Animal
{
public:
	virtual ~Animal() { }
};

class Dog : public Animal { };

int main()
{
	Animal* pa = new Dog;

	Dog* pd = pa; //error

	return 0;
}

 

Animal을 상속받는 Dog이 있을 때, Animal 포인터 타입인 pa로 Dog 객체를 가리킬 수 있다. 그런데 pa는 사실 Dog 객체를 가리키므로, Dog 포인터 타입인 pd로 pa를 가리킬 수 있을까?

 

int main()
{
	...

	Dog* pd = static_cast<Dog*>(pa);

	return 0;
}

 

이처럼 기반 클래스 포인터 타입을 파생 클래스 포인터 타입으로 캐스팅하는 것을 downcasting이라고 하는데, 암시적 형변환이 불가능하기 때문에 위 코드처럼 반드시 명시적으로 캐스팅 해야 한다.

 

class Animal
{
public:
	virtual ~Animal() { }
};

class Dog : public Animal { };
class Cat : public Animal { };

int main()
{
	Animal* pa = new Cat;

	Dog* pd = static_cast<Dog*>(pa);

	return 0;
}

 

이번에는 Animal을 상속받는 Cat을 추가하고, pa가 Cat 객체를 가리키도록 코드를 수정했을 때, 위 코드는 정상적으로 컴파일 될까? static_cast는 컴파일 타임 캐스팅이고, 컴파일 타임에는 pa가 가리키는 메모리를 조사할 수 없기 때문에 잘못된 downcasting을 조사할 수 없다. 따라서 위와 같이 상속 관계의 타입에 대해서는 잘못된 캐스팅이더라도 항상 캐스팅에 성공한다.

 

int main()
{
	Animal* pa = new Cat;

	Dog* pd = dynamic_cast<Dog*>(pa);
	if (pd != nullptr)
	{
		//Do stuff..
	}

	return 0;
}

 

이처럼 잘못된 캐스팅을 방지하기 위해 dynamic_cast를 사용할 수 있다. dynamic_cast는 런 타임 캐스팅이기 때문에, 실행 시간에 pa가 가리키는 곳을 조사하여 잘못된 경우 nullptr을 반환한다. 이때 가상 함수 테이블에 있는 정보를 사용하므로, 가상 함수가 없는 경우 컴파일 에러가 발생한다. 더불어 dynamic_cast는 런 타임 오버헤드가 있기 때문에 반드시 필요한 경우에만 사용하는 것이 좋다.

 

 

 

728x90