정체불명의 모모
[이론] 업캐스팅과 다운캐스팅이란??(필요성, 예제) 본문
업 캐스팅이란?
: 업캐스팅이란 기본 클래스 포인터로 파생클래스 객체를 가리키는 것 입니다.
업 캐스팅을 하게되면 기본 클래스에 정의된 멤버만 호출할 수 있기 때문에 파생 클래스 고유의 기능을 사용할 수가 없습니다.
부모 클래스 -> 자식 클래스
ex ) Parents* parents = new Child;
사용 하는 이유?
: 다형성을 이용해서 코드 재사용성을 높이기 위해서 이다.
예제 코드
#include <iostream>
using namespace std;
class CBase
{
public:
virtual void show()
{
std::cout << "CBase" << std::endl;
}
};
class CDerived1 : public CBase
{
public:
virtual void show()
{
std::cout << "CDerived1"<< std::endl;
}
void print1()
{
std::cout << "============= CDerived1 =============" << std::endl;
}
};
class CDerived2 : public CBase
{
public:
virtual void show()
{
std::cout << "CDerived2" << std::endl;
}
void print2()
{
std::cout << "============ CDerived2 =============" << std::endl;
}
};
int main()
{
CBase* pInterface = nullptr;
CBase* pBase = new CBase;
CDerived1* pDerived1 = new CDerived1;
CDerived2* pDerived2 = new CDerived2;
pInterface = pBase;
pInterface->show();
pInterface = pDerived1;
pInterface->show();
// pInterface->print1(); 파생 클래스의 고유 기능이라 사용할 수 없다.
pInterface = pDerived2;
pInterface->show();
// pInterface->print2(); 파생 클래스의 고유 기능이라 사용할 수 없다.
delete pBase;
delete pDerived1;
delete pDerived2;
return 0;
}
다운 캐스팅이란?
: 다운 캐스팅은 동일한 타입의 포인터가 동일한 타입을 가리키는 것 입니다.
파생 클래스 포인터 -> 파생 클래스 객체
사용 하는 이유?
: 다형성 과 코드 재사용성을 높이기 위해
업 캐스팅을 하게 되면 기본 클래스에 정의된 멤버만 호출할 수 있기 때문에 파생클래스 고유의 기능을 사용할 수 없습니다.
그렇기에 잠시 다운캐스팅을 해서 기본 클래스 포인터 -> 파생 클래스 객체의 형태에서 ,
파생 클래스 포인터 -> 파생클래스 객체 형태로 타입 변환을 해줘 파생 클래스의 고유 기능을 사용합니다.
다운 캐스팅 할 때 주의 할 점
- 서로 동일한 타입이어야 한다.
- 형 변환시에는 반드시 명시적 형 변환을 해줘야 한다.
(수 많은 파생 클래스 중에 해당 객체가 어떤 타입인지 명시를 해주지 않는다면 에러를 발생시킬 수 있기 때문에)
다운 캐스팅 예제
#include <iostream>
#include <map>
#include <string>
using namespace std;
class CBase
{
public:
virtual void show()
{
cout << "CBase" << endl;
}
void A()
{
cout << "A의 고유 기능" << endl;
}
};
class CDerived1 : public CBase
{
public:
virtual void show()
{
cout << "CDerived1" << endl;
}
void B()
{
cout << "B의 고유 기능" << endl;
}
};
class CDerived2 : public CBase
{
public:
virtual void show()
{
cout << "CDerived2" << endl;
}
void C()
{
cout << "C의 고유 기능" << endl;
}
};
int main()
{
string classNames[3] = {"CBase" ,"CDerived1", "CDerived2"};
string className = "";
std::map<string , CBase*> mapData;
CBase* pInterface = nullptr;
CBase* pBase = new CBase;
CDerived1* pDerived1 = new CDerived1;
CDerived2* pDerived2 = new CDerived2;
mapData.insert(std::make_pair(classNames[0],pBase));
mapData.insert(std::make_pair(classNames[1],pDerived1));
mapData.insert(std::make_pair(classNames[2],pDerived2));
for(int i = 0 ; i < mapData.size(); i++)
{
className = classNames[i];
pInterface = mapData.find(className)->second; // 업 캐스팅
switch (i)
{
case 0:
pBase = (CBase*)pInterface; // 다운 캐스팅(pInterface를 CBase로 타입 캐스팅
pBase->A();
break;
case 1:
pDerived1 = (CDerived1*)pInterface; // 다운 캐스팅(pInterface를 pDerived1로 타입 캐스팅
pDerived1->B();
break;
case 2:
pDerived2 = (CDerived2*)pInterface;
pDerived2->C();
break;
default:
break;
}
}
mapData.clear();
delete pBase;
delete pDerived1;
delete pDerived2;
return 0;
}
참고 사이트 (예제 참고)
↓ 아래사이트 정리 진짜 잘해 놓으셨어요!! 한번 꼭 읽어 보세요!
https://rehtorb-algorithm.tistory.com/8
'프로그래밍(c++)' 카테고리의 다른 글
[c언어] Mutex , cond 기본정리 (0) | 2021.09.14 |
---|---|
[c++]static_cast 란? (0) | 2021.09.08 |
[c++] dynamic_cast 란? (2) | 2021.09.08 |
[C++] 상속 관계에서 생성자, 소멸자 호출 순서 / virtual 소멸자 (0) | 2021.08.11 |
[C++/STL] vector와 deque의 차이점 (0) | 2021.08.10 |
Comments