갓똥
나는야 프로그래머
갓똥
전체 방문자
오늘
어제
  • 분류 전체보기 (186)
    • 프로그래밍 (146)
      • 자바 (9)
      • 안드로이드 (2)
      • 유니티 (20)
      • C++ (38)
      • C# (56)
      • HTML (2)
      • 파이썬 (3)
      • 자료구조 (2)
      • 알고리즘 (0)
      • 문제풀이 (4)
      • 디자인 패턴 (7)
      • 카카오톡 봇 (1)
      • 엑셀 (1)
      • 기타 (1)
    • 게임 (21)
      • 테일즈위버 (0)
      • 카이로소프트 (1)
      • 순위 (19)
      • 기타 (1)
    • 일상 (13)
      • 카페 (1)
      • 방탈출 (12)
    • 기타 (6)
      • 웃긴자료 (5)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

태그

  • c# Thread
  • c# delegate
  • 롤 골드그래프
  • c# unboxing
  • 유니티 그래프 그리기
  • 유니티 골드그래프
  • pc 게임 순위
  • 강남 방탈출
  • 전세계게임매출순위
  • C# 예외 처리
  • 게임 디자인 패턴
  • 자바
  • 알고리즘
  • 2020년 게임 매출
  • C++ 상속
  • C++
  • C++ virtual
  • 게임 매출 순위
  • c# collection
  • c# coroutine
  • C++ 소멸자
  • pc게임 순위
  • Unity Graph
  • C# boxing
  • 모바일 게임 순위
  • 유니티 그래프
  • 글로벌게임매출
  • c# 코루틴
  • 게임매출순위
  • 전세계 게임 매출

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갓똥

나는야 프로그래머

[C++] upcasting
프로그래밍/C++

[C++] upcasting

2019. 11. 26. 22:56
728x90
반응형

1. 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 = ▭ // ??
    
    Shape& r = rect;   // ??
}

 

main함수를 살펴보자
1. Rect* p1 = ▭ 
  - 서로 똑같은 타입으로 아무 문제 없이 ok.
2. int* p2 = ▭
  - 이건 완벽히 다른 타입으로 error / 리인터프리터 캐스팅을 사용하면 가능
3. Shape* p3 = ▭
  - 앞에 포인터가 Rect는 아니지만 기반 클래스 타입인 경우는 어떨까?

p3의 주소를 따라가면 Shape가 있을 것이다.
해서 따라가면 Rect에 Shape가 있으므로 문제가 없음.

4. Shape& r = rect;
  - rect를 포인터가 아닌 참조로 가르킴. rect의 앞 부분에는 Shape가 있으므로 ok

  ① Up casting

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

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

 


2. 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;     // ??
}

 

컴파일러는 Shape포인터로 생각하는데
p->color = 0; 의 경우 Shape의 멤버데이터 이므로 문제 없지만
p->x = 0; 의 경우 Shape가 없기 때문에 에러가 나게됨.
해결 방법은?
    static_cast<Rect*>(p)->x = 0;

  ① 기반 클래스 타입의 포인터로 파생 클래스를 가리킬 때

    => 기반 클래스의 멤버는 접근할 수 있지만

    => 파생 클래스가 추가한 멤버는 접근할 수 없다.

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

 


3. upcasting 활용

class Shape {
public:
    int color;
};

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

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

int main() {
    Rect r;
    changeBlack(&r);
}

 

위의 코드에서 changeBlack함수는 인자로 받은 사각형의 색상을 검은색으로 바꿔주는 코드이다.
하지만 위 코드의 문제는 사각형만 바꿀 수 있다는 점이다.
Shape를 상속받을 Triangle, pentagon등이 추가된다면 그에 맞는 함수를 똑같이 또 만들어야한다.
void changeBlack(Shape* p) {
    p->color = 0;
}

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

 

또한 도형을 보관하는 buffer를 만든다고 생각해봤을 때
Rect* buffer[10];의 경우 사각형만 보관할 수 있다. 이럴경우에는
    Rect* buffer[10];  // 사각형만 보관
    Shape* buffer[10]; // 모든 도형 보관

  ② 동종 (동일한 기반 클래스를 사용하는 클래스)을 보관하는 컨테이너를 만들 수 있다.

728x90
반응형

'프로그래밍 > C++' 카테고리의 다른 글

[C++] 가상 함수 문법 정리  (0) 2019.11.28
[C++] 가상 함수 (virtual function)  (2) 2019.11.26
[C++] 상속에서의 생성자 소멸자  (0) 2019.11.26
[C++] 상속과 접근 지정자 (access specifiers)  (1) 2019.11.25
[C++] 상속  (0) 2019.11.24
    '프로그래밍/C++' 카테고리의 다른 글
    • [C++] 가상 함수 문법 정리
    • [C++] 가상 함수 (virtual function)
    • [C++] 상속에서의 생성자 소멸자
    • [C++] 상속과 접근 지정자 (access specifiers)
    갓똥
    갓똥
    공부하며 알아가는 내용을 정리해 봅니다.

    티스토리툴바