본문 바로가기
  • 쓸쓸한 개발자의 공부방
C++

[C++] upcasting (업캐스팅)

by 심찬 2021. 8. 27.

 

 

upcasting (업캐스팅)

 

 - 기반 클래스 타입의 포인터로 파생 클래스를 가리킬 수 있다.

 - 기반 클래스 타입의 참조로 파생 클래스를 가리킬 수 있다.

class Shape
{
public:
    int color;
};

class Rect : public Shape
{
public:
    int x, y, w, h;
};

int main()
{
    Rect rect;
    
    Rect*  p1 = ▭ // ok
    int*   p2 = ▭ // error. 
    Shape* p3 = ▭ // ok  
    
    Shape& r = rect;   // ok. 
    
}

main.cpp:18:18: error: cannot convert ‘Rect*’ to ‘int*’ in initialization

Shape* p3 = ▭    // ok!

Rect 형 객체가 생성된 곳에 가면 Shape 를 상속 받고 있기 때문에 Shape가 있으니 문제 없다고 판단한다.

-> Rect 타입을 Shape* 타입으로 암시적 형변환이 일어난다. => upcasting

 

 

upcasting 된 객체에서 파생 클래스에 접근

 

파생 클래스가 추가한 멤버에 접근 하려면 포인터를 파생 클래스 타입으로 캐스팅 해야 한다.

 

class Shape
{
public:
    int color;
};
class Rect : public Shape
{
public:
    int x, y, w, h;
};

int main()
{
    Rect rect;

    Shape* p = ▭ 
    
    p->color = 0; // ok
    p->x = 0;     // error
    static_cast<Rect*>(p)->x = 0; // ok
    
}

p는 Shape* 형태이기 때문에 p->x로 접근을 시도할 때 Share에 정의된 x를 찾는다.

사용을 하기 위해서는 static_cast를 통해서 x로 접근이 가능하다.

 

    p->x = 0;     // error
    static_cast<Rect*>(p)->x = 0; // ok

 

 

upcasting 활용법

 

동일한 기반 클래스를 사용하는 클래스를 처라하는 함수를 만들 수 있다. (동종을 만들 수 있다. )

void changeBlack(Shape* p)
{
    p->color = 0;
}

동일 기반 클래스를 사용하는 경우 동종을 보관하는 컨테니어를 만들 수 있다. (즉, Shape* 형태를 보관하는 컨테이너를 만들 수 있다.)

class Shape
{
public:
    int color;
};
class Rect : public Shape
{
public:
    int x, y, w, h;
};

// 인자로 전달된 도형을 검정색으로 변경하는 함수
void changeBlack(Shape* p)
{
    p->color = 0;
}
/*
void changeBlack(Triangle* p)
{
    p->color = 0;
}
*/
int main()
{
    Rect r;
    changeBlack(&r);
    
    Rect* buffer[10]; // 사각형만 보관
    Shape* buffer[10]; // 모든 도형 보관
}

 

댓글