Menu
CoddyTech

업캐스팅

Coddy C 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 61개 중 31번째.

업캐스팅은 특정(파생) 타입을 더 일반적인(기본) 타입으로 취급하는 것입니다. C의 합성 모델에서는 기본 타입을 포함하는 구조체의 포인터를 기본 타입을 기대하는 함수에 전달하는 것을 의미합니다.

Vehicle 기본 구조체와 이를 포함하는 Car를 살펴보세요.

typedef struct {
    int speed;
} Vehicle;

typedef struct {
    Vehicle vehicle;  // 첫 번째 멤버로 배치한 베이스
    int doors;
} Car;

이제 모든 차량에서 작동하는 일반 함수를 상상해 보세요.

void accelerate(Vehicle* v, int amount) {
    v->speed += amount;
}

첫 번째 멤버 규칙 덕분에 Car*를 Vehicle*로 캐스팅하여 이 함수에 전달할 수 있습니다:

Car my_car = {{0}, 4};  // speed=0, doors=4
accelerate((Vehicle*)&my_car, 50);
printf("Speed: %d\n", my_car.vehicle.speed);  // 출력: 50

이것이 업캐스팅입니다. 특정 타입에서 일반적인 타입으로 "위로" 이동하는 것입니다. 함수 accelerate는 Car와 함께 작동한다는 것을 알지 못하고, Vehicle만 봅니다. 이를 통해 기본 타입을 사용하는 동시에 그 타입을 포함하는 파생 타입을 무엇이든 받을 수 있는 재사용 가능한 코드를 작성할 수 있습니다.

challenge icon

챌린지

쉬움

실제 동작을 통해 업캐스팅을 보여 주는 간단한 운송 시스템을 만들어 봅시다. 기본 Vehicle 타입과 더 구체적인 Motorcycle 타입을 만들고, 포인터 캐스팅을 통해 일반 함수가 두 타입 모두에서 어떻게 동작하는지 확인합니다.

업캐스팅의 장점은 기본 타입을 위한 함수를 작성하면 해당 기본 타입을 포함하는 파생 타입에서도 문제없이 사용할 수 있다는 것입니다. 오토바이는 차량의 한 종류이므로, Vehicle*를 받는 함수라면 오토바이도 처리할 수 있어야 합니다.

코드를 세 개의 파일로 구성합니다:

  • vehicle.h: 인클루드 가드를 사용해 구조체 계층을 정의합니다. 두 개의 필드가 있는 Vehicle 구조체를 만듭니다. speed는 현재 속도를 나타내는 정수이고, max_speed는 차량의 최고 속도를 나타내는 정수입니다. 그런 다음 Vehicle을 첫 번째 멤버로 포함하고 has_sidecar 필드(정수이며, 1은 예, 0은 아니요를 의미)를 추가하는 Motorcycle 구조체를 정의합니다. 두 개의 함수를 선언합니다. boost는 Vehicle*와 속도를 높일 양을 받고, print_motorcycle는 Motorcycle*를 받습니다.
  • vehicle.c: 두 함수를 모두 구현합니다. boost 함수는 주어진 양만큼 차량 속도를 높여야 하지만, 속도가 max_speed를 초과하지 않도록 제한해야 합니다. 새 속도가 최고 속도를 초과하면 대신 max_speed로 설정합니다. print_motorcycle 함수는 포함된 차량 데이터 등 오토바이의 모든 정보를 출력해야 합니다.
  • main.c: Motorcycle을 만들고 모든 필드를 초기화합니다. 그런 다음 boost 함수를 호출해 업캐스팅을 보여 줍니다. 이 일반 함수에 전달할 수 있도록 Motorcycle*을 Vehicle*로 캐스팅합니다. 속도를 높인 뒤 오토바이 정보를 출력해 결과를 확인합니다.

네 가지 입력값을 받습니다. 오토바이의 초기 속도, 최고 속도, 사이드카가 있는지 여부(1 또는 0), 그리고 속도 증가량입니다.

출력은 다음과 같아야 합니다:

Speed: 75
Max Speed: 120
Sidecar: Yes

여기서 75는 속도를 높인 후의 속도(초기 속도 50 + 증가량 25)이고, 120은 최고 속도이며, Yes 또는 No는 오토바이에 사이드카가 있는지를 나타냅니다. 속도 증가로 최고 속도를 초과하게 된다면 속도는 max_speed로 제한해야 합니다.

여기서 핵심적으로 배울 점은 boost가 오토바이에 대해 아무것도 모른다는 것입니다. 이 함수는 Vehicle만 다룹니다. 하지만 업캐스팅을 통해 오토바이도 이 일반 함수를 사용해 포함된 차량 데이터를 수정할 수 있습니다.

직접 해보기

#include <stdio.h>
#include "vehicle.h"

int main() {
    int initial_speed, max_speed, has_sidecar, boost_amount;
    
    // 입력값을 읽습니다
    scanf("%d", &initial_speed);
    scanf("%d", &max_speed);
    scanf("%d", &has_sidecar);
    scanf("%d", &boost_amount);
    
    // TODO: Motorcycle을 생성하고 모든 필드를 초기화합니다
    // 기억하세요: Motorcycle은 Vehicle을 첫 번째 멤버로 포함합니다
    
    // TODO: boost를 호출하여 업캐스팅을 보여 줍니다
    // boost 함수에 전달할 수 있도록 Motorcycle*를 Vehicle*로 형변환합니다
    
    // TODO: 모터사이클의 정보를 출력합니다
    
    return 0;
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 C 컴파일러