Menu
CoddyTech

불투명 구조체 정의하기

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

불투명 포인터의 개념을 이해했으니, 이제 이 패턴을 완성하는 방법을 살펴보겠습니다. 헤더에서는 형식이 존재한다고 선언하지만, 실제 내부 내용을 정의하는 곳은 소스 파일입니다.

전체 설정은 다음과 같습니다. 먼저 전방 선언만 포함된 헤더입니다:

// counter.h
#ifndef COUNTER_H
#define COUNTER_H

typedef struct Counter Counter;  // 불완전한 타입

Counter *create_counter(int start);
void free_counter(Counter *c);

#endif

그런 다음 소스 파일에는 실제 구조체 정의가 들어 있습니다.

// counter.c
#include "counter.h"
#include <stdlib.h>

struct Counter {
    int value;      // 외부에서는 볼 수 없습니다!
    int step;
};

Counter *create_counter(int start) {
    Counter *c = malloc(sizeof(Counter));
    c->value = start;
    c->step = 1;
    return c;
}

void free_counter(Counter *c) {
    free(c);
}

핵심은 struct Counter { ... }가 .c 파일에만 나타난다는 점입니다. counter.h를 포함하는 파일은 Counter가 존재한다는 것은 알지만, value나 step은 볼 수 없습니다. main.c에서 c->value를 작성하려고 하면 컴파일러 오류가 발생합니다. 멤버가 실제로 보이지 않기 때문입니다.

이러한 분리는 C에서 캡슐화의 기반입니다. 다음 단계는 getter 및 setter 함수를 통해 제어된 접근을 제공하는 것입니다.

challenge icon

챌린지

쉬움

불투명 포인터 패턴을 보여 주는 Timer 모듈을 만들어 봅시다. 소스 파일 안에 구조체 정의를 숨겨 모듈을 사용하는 코드에서 내부 멤버를 완전히 볼 수 없도록 하는 방법을 연습합니다.

세 개의 파일을 만들겠습니다.

  • timer.h: 공개 인터페이스입니다. 전방 선언만 사용해 불투명한 Timer 타입을 선언하세요. 여기에는 구조체 본문을 작성하지 마세요! 함수 두 개도 선언하세요. create_timer는 초를 나타내는 정수를 받아 Timer 포인터를 반환하고, free_timer는 Timer 포인터를 받아 정리합니다. 기호 TIMER_H를 사용해 인클루드 가드를 작성하세요.
  • timer.c: 비밀이 숨겨진 곳입니다. 숨겨진 멤버 두 개, 즉 int seconds와 int running을 가진 실제 struct Timer를 정의하세요. 실행 중일 때는 1, 중지했을 때는 0을 사용합니다. 구조체에 메모리를 할당하고, 제공된 값으로 seconds를 초기화한 다음 running을 1로 설정하는 생성자를 구현하세요. 메모리를 해제하는 소멸자도 구현하세요.
  • main.c: Timer 모듈을 사용해 타이머를 만들고 정상적으로 생성되었는지 확인하세요. 구조체 멤버는 숨겨져 있으므로 직접 접근할 수 없습니다. 바로 이 점이 핵심입니다! 생성 확인 메시지를 출력하고, 타이머를 해제한 다음 정리 확인 메시지를 출력하세요.

입력은 하나입니다. 타이머를 초기화할 초 수(정수)를 받습니다.

메인 파일에서 제공된 초 값으로 타이머를 만드세요. 생성 메시지를 출력한 다음 타이머를 해제하고 확인 메시지를 출력하세요.

다음 형식으로 출력을 표시하세요.

Timer created
Timer freed

여기서 핵심은 main.c가 Timer 포인터를 사용할 수는 있지만 seconds나 running에 직접 접근할 방법은 없다는 점입니다. main.c에서 t->seconds를 작성하려고 하면 구조체 본문이 timer.c에만 정의되어 있기 때문에 컴파일러 오류가 발생합니다. 이것이 진정한 캡슐화입니다. 구현 세부 정보가 모듈 사용자에게 완전히 숨겨집니다.

직접 해보기

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

int main() {
    int seconds;
    scanf("%d", &seconds);
    
    // TODO: 제공된 seconds 값으로 timer를 생성하세요
    
    // TODO: "Timer created"을 출력하세요
    
    // TODO: timer를 해제하세요
    
    // TODO: "Timer freed"을 출력하세요
    
    return 0;
}
quiz icon실력 점검

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

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

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