C++ 추상 클래스와 순수 가상 함수 개념 정리: 예제와 함께 쉽게 이해하기
📌 객체지향의 핵심, C++ 추상 클래스 제대로 이해하고 사용해보세요!
프로그래밍을 하다 보면 꼭 마주하게 되는 개념이 있습니다.
바로 순수 가상 함수와 추상 클래스인데요.
이 두 개념은 C++에서 객체지향 프로그래밍(OOP)을 구현할 때 정말 중요한 요소입니다.
하지만 처음 접할 땐 다소 낯설고 어렵게 느껴질 수 있어요.
이 글에서는 C++ 초보자도 쉽게 이해할 수 있도록, 순수 가상 함수가 무엇인지, 추상 클래스가 왜 필요한지, 그리고 실제로 어떻게 사용하는지까지 친절히 안내해드릴게요.
마치 수업을 듣듯 차근차근 따라오시면 어느새 개념이 확실하게 잡혀 있을 거예요!
여러분은 클래스 안에 구현 없이 선언만 되어 있는 함수 보신 적 있으신가요?
그런 함수가 바로 순수 가상 함수(pure virtual function)입니다.
그리고 그런 함수를 하나라도 포함한 클래스는 추상 클래스(abstract class)라고 부르죠.
이런 클래스는 직접 객체를 만들 수는 없지만, 공통 인터페이스를 제공해서 다형성을 실현하는 데 큰 역할을 합니다.
이 글에서는 이러한 개념을 이론과 함께 예제 코드로 이해하고, 실제 개발에 어떻게 적용할 수 있을지 배워볼 거예요.
📋 목차
🔗 순수 가상 함수란?
C++에서 클래스 안에 선언된 함수가 구현 없이 선언만 되어 있을 때, 이를 순수 가상 함수(Pure Virtual Function)라고 부릅니다.
형태는 다음과 같이 생겼어요.
class Shape {
public:
virtual void draw() = 0; // 순수 가상 함수
};
위 코드에서 draw()는 본문이 없이 = 0으로 끝나는데, 이게 바로 순수 가상 함수의 문법이에요.
즉, 이 함수는 자식 클래스에서 반드시 오버라이딩해서 사용해야 합니다.
순수 가상 함수는 일반적인 가상 함수와는 달리, 기본 동작이 없기 때문에 직접 사용할 수 없고, 해당 함수를 사용하는 객체는 구체적인 구현을 제공해야만 쓸 수 있답니다.
💡 TIP: 순수 가상 함수는 특정 기능이 꼭 필요하다는 것을 자식 클래스에게 강제할 때 사용합니다.
실제 구현은 자식 클래스에서 맡게 되죠.
이러한 특성 때문에 순수 가상 함수를 포함한 클래스는 객체를 직접 생성할 수 없고, 반드시 상속을 통해 사용해야 한다는 점도 중요합니다.
다음 섹션에서 이와 관련된 추상 클래스 개념을 자세히 알아보겠습니다.
🛠️ 추상 클래스의 역할과 특징
순수 가상 함수를 하나라도 포함하고 있다면, 그 클래스는 자동으로 추상 클래스(Abstract Class)가 됩니다.
추상 클래스는 말 그대로 ‘추상적인 틀’만 제공하고, 직접적으로 객체를 생성할 수 없습니다.
즉, new 키워드로 인스턴스를 만들 수 없는 클래스라는 거죠.
추상 클래스의 주된 목적은 공통된 기능을 정의한 ‘인터페이스’ 역할입니다.
여기서 핵심은 “공통의 약속”을 정해주는 것이에요.
이 약속을 따르도록 자식 클래스는 반드시 순수 가상 함수를 구현해야 하고요.
class Shape {
public:
virtual void draw() = 0; // 순수 가상 함수 → 추상 클래스
};
class Circle : public Shape {
public:
void draw() override {
// 원 그리기 로직 구현
}
};
위 예제처럼 Shape는 추상 클래스이고, Circle은 그걸 상속받아 실제 구현을 제공합니다.
이렇게 여러 파생 클래스가 공통된 인터페이스를 따르도록 구조화하면, 유지보수성과 확장성이 매우 높아지죠.
💎 핵심 포인트:
추상 클래스는 공통 인터페이스를 정의하고, 구체적인 동작은 자식 클래스가 구현합니다. C++의 다형성과 매우 밀접하게 연관된 구조입니다.
정리하자면, 추상 클래스는 단독으로는 사용할 수 없지만, 코드의 구조와 약속을 정립하는 데 매우 유용합니다.
객체지향 설계에서 필수적으로 활용되는 개념이니 꼭 익혀두세요!
⚙️ 인터페이스와의 관계
C++에는 interface라는 키워드가 따로 없지만, 추상 클래스는 사실상 인터페이스처럼 활용됩니다.
특히, 모든 멤버 함수가 순수 가상 함수인 클래스는 완벽한 인터페이스로 동작하게 되죠.
아래 예제를 보시면, 전형적인 C++ 인터페이스 형식을 확인할 수 있습니다.
class IPrintable {
public:
virtual void print() = 0;
virtual ~IPrintable() {}
};
여기서 IPrintable은 함수 구현 없이 순수 가상 함수만 포함하고 있으며, 소멸자도 가상 소멸자로 선언되어 있죠.
이런 구조가 바로 다른 언어의 interface와 동일한 개념입니다.
💡 TIP: C++에서는 여러 개의 인터페이스(추상 클래스)를 다중 상속받는 방식으로 유연한 설계가 가능합니다. 단, 복잡한 상속 구조는 주의가 필요해요.
이러한 추상 클래스를 인터페이스처럼 설계해두면, 다형성을 활용해 다양한 객체를 동일한 방식으로 처리할 수 있어 코드의 유연성과 확장성이 크게 향상됩니다.
결론적으로 C++에서 추상 클래스는 인터페이스의 핵심 역할을 수행하며, 객체지향 설계의 중심축이 됩니다.
🔌 실제 코드 예제로 개념 익히기
이제 이론만 듣는 걸 넘어, 실제 코드 예제를 통해 순수 가상 함수와 추상 클래스 개념을 실습해보겠습니다.
아래 예제는 기본적인 도형 클래스 구조를 정의하고, 각 도형이 draw()라는 기능을 자신만의 방식으로 구현하는 모습입니다.
#include <iostream>
using namespace std;
class Shape {
public:
virtual void draw() = 0; // 순수 가상 함수
};
class Circle : public Shape {
public:
void draw() override {
cout << "원을 그립니다." << endl;
}
};
class Rectangle : public Shape {
public:
void draw() override {
cout << "사각형을 그립니다." << endl;
}
};
int main() {
Shape* s1 = new Circle();
Shape* s2 = new Rectangle();
s1->draw(); // 원을 그립니다.
s2->draw(); // 사각형을 그립니다.
delete s1;
delete s2;
return 0;
}
이 예제를 통해 확인할 수 있는 핵심은 다음과 같습니다.
- 🔎Shape는 추상 클래스이며 인스턴스화할 수 없습니다
- 🧩draw()는 자식 클래스에서 반드시 구현해야 합니다
- 🌀다형성을 통해 같은 인터페이스로 다양한 행동을 수행할 수 있습니다
이처럼 추상 클래스를 이용하면 공통된 규약을 정해두고, 각 하위 클래스에서 자신만의 동작을 구현할 수 있어 매우 강력한 구조를 만들 수 있어요.
개념을 이해했다면, 여러분도 직접 도전해보세요!
💡 실무에서 자주 쓰이는 패턴
추상 클래스와 순수 가상 함수는 실무에서 디자인 패턴과 함께 자주 활용됩니다.
대표적으로 많이 쓰이는 패턴은 다음과 같습니다.
템플릿 메서드 패턴
공통된 알고리즘의 구조는 상위 클래스에서 정의하고, 세부 동작은 하위 클래스에서 구현하는 방식입니다.
순수 가상 함수는 이때 필수 구현 지점을 표시하는 역할을 하죠.
class DataProcessor {
public:
void process() {
loadData();
analyze();
report();
}
virtual void loadData() = 0;
virtual void analyze() = 0;
virtual void report() = 0;
};
전략 패턴
기능을 추상 클래스로 분리하고, 런타임에 해당 기능을 자유롭게 교체할 수 있도록 설계합니다.
AI, 게임 개발, UI 애니메이션 등 다양한 분야에서 많이 활용돼요.
인터페이스 분리 원칙 (ISP)
클래스가 필요하지 않은 함수까지 구현하지 않도록, 작은 단위의 인터페이스를 분리하는 원칙입니다.
C++에서는 여러 개의 추상 클래스를 조합해서 구현할 수 있어요.
⚠️ 주의: 다중 상속으로 여러 추상 클래스를 동시에 상속받을 경우, 가상 상속(virtual inheritance)을 고려하지 않으면 충돌이 발생할 수 있어요.
이처럼 추상 클래스와 순수 가상 함수는 C++ 실무 설계에서 핵심적인 도구로 사용됩니다.
다양한 디자인 패턴과 원칙에 적절히 활용하면 확장성 있고 유지보수하기 쉬운 코드를 만들 수 있답니다.
❓ 자주 묻는 질문 (FAQ)
순수 가상 함수와 일반 가상 함수의 차이는 무엇인가요?
= 0으로 선언됩니다. 순수 가상 함수는 반드시 자식 클래스에서 오버라이딩해야 합니다.
추상 클래스는 객체를 만들 수 없나요?
C++에서는 interface 키워드가 없는데 어떻게 인터페이스를 구현하나요?
순수 가상 함수는 몇 개 이상 있어야 추상 클래스가 되나요?
추상 클래스 안에 일반 함수도 포함할 수 있나요?
소멸자는 왜 가상으로 선언해야 하나요?
추상 클래스는 다중 상속이 가능한가요?
추상 클래스를 사용하는 가장 큰 장점은 무엇인가요?
📌 추상 클래스와 순수 가상 함수로 확장성 있는 C++ 코딩하기
추상 클래스와 순수 가상 함수는 C++에서 객체지향 프로그래밍을 구현하는 핵심 도구입니다.
이 글에서는 순수 가상 함수의 정의와 문법, 추상 클래스의 역할과 실질적인 사용 방법, 그리고 인터페이스와의 관계까지 폭넓게 다뤘습니다.
또한 실제 예제를 통해 개념을 시각화하고, 실무에서 자주 쓰이는 디자인 패턴과의 연결점도 살펴보았습니다.
이러한 개념들은 단순히 문법적 요소에 그치지 않고, 소프트웨어 설계의 품질을 높이는 데 필수적인 역할을 합니다.
유지보수가 쉽고 확장 가능한 코드를 작성하고자 한다면 반드시 익혀야 할 개념이죠.
특히 다양한 객체를 공통된 인터페이스로 처리하고 싶은 상황에서는 추상 클래스를 적극 활용해보세요.
앞으로의 프로젝트에서 추상 클래스와 순수 가상 함수가 어떻게 쓰일 수 있을지 떠올려보며 직접 코드를 작성해보는 것도 좋은 연습이 될 거예요.
꾸준히 연습하다 보면 객체지향 설계에 대한 감각이 확실히 향상될 거라 자신 있게 말씀드립니다.
🏷️ 관련 태그:C++객체지향, 추상클래스, 순수가상함수, C++인터페이스, 다형성, C++디자인패턴, 템플릿메서드, 전략패턴, virtual함수, C++클래스