정체불명의 모모

[이론] 업캐스팅과 다운캐스팅이란??(필요성, 예제) 본문

프로그래밍(c++)

[이론] 업캐스팅과 다운캐스팅이란??(필요성, 예제)

정체불명의 모모 2021. 9. 8. 17:18
업 캐스팅이란?

: 업캐스팅이란 기본 클래스 포인터로 파생클래스 객체를 가리키는 것 입니다.

  업 캐스팅을 하게되면 기본 클래스에 정의된 멤버만 호출할 수 있기 때문에 파생 클래스 고유의 기능을 사용할 수가 없습니다.

부모 클래스 ->  자식 클래스
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++] 업 캐스팅(up casting) & 다운 캐스팅(down casting)

포인터는 왜쓰고 업&다운 캐스팅은 뭘까요? 설명에 앞서 저는 업캐스팅을 이해하려면 포인터부터 알아야 한다고 생각합니다. 해서 포인터부터 설명을 드리겠습니다. 학창시절 포인터는 C에서

rehtorb-algorithm.tistory.com

 

Comments