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 |