C++의 다형성과 C의 함수 포인터 테이블
이 레슨에서는 C++의 가상 함수와 C의 함수 포인터로 여러 종류의 객체에 같은 연산을 호출합니다.
소개
동적 다형성(dynamic polymorphism)은 코드가 넓이 계산 같은 공통 연산을 호출하고, 그 연산을 어떻게 할지는 각 객체 타입이 스스로 정하게 합니다. C++는 가상 함수(virtual functions)로 이를 직접 지원하며, C에서는 함수 포인터로 흉내 낼 수 있습니다.
핵심 정리
- C++의 추상화를 배우기 전에 C에서는 어떻게 하는지 이해하세요.
- 자원의 소유권은 RAII와 값 의미론(value semantics)으로 표현하세요.
- 매크로와 타입 변환보다 C++의 타입 안전한 도구를 쓰세요.
C와 C++ 코드 예제
C
main.c
#include <stdio.h>
typedef struct Shape Shape;
struct Shape {
double value;
double (*area)(const Shape *shape);
};
double square_area(const Shape *shape) {
return shape->value * shape->value;
}
int main(void) {
Shape square = {4.0, square_area};
printf("area=%.1f\n", square.area(&square));
}
area=16.0
C++
main.cpp
#include <iostream>
struct Shape {
virtual double area() const = 0;
virtual ~Shape() = default;
};
struct Square : Shape {
double side;
explicit Square(double value) : side(value) {}
double area() const override { return side * side; }
};
int main() {
Square square(4);
const Shape& shape = square;
std::cout << "area=" << shape.area() << '\n';
}
area=16
C와 C++ 비교
C의 struct Shape에는 함수 포인터 area가 들어 있고, 도형마다 square_area처럼 자기만의 넓이 계산 함수를 연결합니다. C++에서는 가상 함수가 같은 선택 메커니즘을 자동으로 만들어 줍니다. 기반 클래스 포인터로 객체를 안전하게 삭제하려면 기반 클래스에 가상 소멸자(virtual destructor)도 있어야 합니다.
C
C는 이름 짓기 관례, 콜백, 매크로, 컨텍스트 struct를 씁니다.
C++
C++는 범위가 분명하고 타입 안전하며, 보통 실행 시 추가 비용이 없는 추상화를 제공합니다.
연습 문제
두 버전을 모두 실행한 다음 코드를 바꿔 보면서 각 언어가 주는 안전성의 차이를 살펴보세요.
- 먼저 C로 동작 원리를 작성한 다음 C++의 같은 기능을 써 보세요.
- 직접 하던 자원 해제를 RAII로 바꿔 보세요.
- 그 기능이 메모리 할당이나 가상 함수 호출을 일으키는지 확인해 보세요.
챌린지로 연습하기
이 레슨에서 배운 내용으로 실제 문제를 풀어 보세요. 모든 챌린지는 브라우저에서 실행되며 즉시 테스트와 AI 리뷰를 받을 수 있습니다.
모든 챌린지