추상 클래스는 객체 지향 프로그래밍에서 중요한 개념으로, 하나 이상의 순수 가상 함수를 포함하는 클래스를 말합니다.
추상 클래스의 주요 목적은 공통된 인터페이스를 정의하고 파생 클래스에서 이를 구현하도록 강제하는 것입니다.
추상 클래스의 특징
직접적인 인스턴스화 불가능
포인터나 참조를 통해 사용 가능
파생 클래스에서 모든 순수 가상 함수를 구현해야 함
일반 멤버 변수와 일반 멤버 함수도 포함할 수 있음
순수 가상 함수
순수 가상 함수는 기본 클래스에서 구현을 제공하지 않는 가상 함수입니다.
함수 선언 뒤에 = 0을 붙여 나타냅니다.
순수 가상 함수의 특징
기본 클래스에서 구현을 제공하지 않음
파생 클래스에서 반드시 구현해야 함
인터페이스를 정의하는 데 사용됨
추상 클래스 vs 구체 클래스
추상 클래스를 상속받아 모든 순수 가상 함수를 구현한 클래스를 구체 클래스라고 합니다.
인터페이스 클래스
C++에는 Java나 C#과 같은 interface 키워드가 없지만, 순수 가상 함수만을 포함하는 추상 클래스를 통해 인터페이스를 구현할 수 있습니다.
추상 클래스의 활용
다형성 구현
추상 클래스를 사용하면 다형성을 효과적으로 구현할 수 있습니다.
프레임워크 설계
추상 클래스는 프레임워크나 라이브러리 설계에 자주 사용됩니다.
기본 동작을 정의하고 사용자가 특정 동작을 재정의할 수 있게 합니다.
추상 클래스와 순수 가상 함수의 고급 기능
순수 가상 함수의 구현 제공
순수 가상 함수에도 기본 구현을 제공할 수 있습니다.
이 경우 파생 클래스에서 해당 함수를 반드시 재정의할 필요는 없지만, 클래스는 여전히 추상 클래스로 남습니다.
추상 클래스의 생성자와 소멸자
추상 클래스도 생성자와 소멸자를 가질 수 있습니다.
이들은 파생 클래스의 객체가 생성되거나 소멸될 때 호출됩니다.
추상 클래스와 다중 상속
C++에서는 다중 상속을 지원하므로, 여러 추상 클래스를 동시에 상속받을 수 있습니다.
이를 통해 여러 인터페이스를 구현하는 클래스를 만들 수 있습니다.
추상 클래스와 템플릿
추상 클래스와 템플릿을 조합하여 유연하고 재사용 가능한 코드를 작성할 수 있습니다.
추상 클래스와 순수 가상 함수의 장단점
장점
인터페이스 정의 : 공통된 인터페이스를 정의하여 코드의 일관성을 유지할 수 있습니다.
다형성 : 기본 클래스 포인터나 참조를 통해 파생 클래스 객체를 다룰 수 있습니다.
코드 재사용 : 공통 기능을 기본 클래스에 구현하여 코드 중복을 줄일 수 있습니다.
확장성 : 새로운 파생 클래스를 쉽게 추가할 수 있습니다.
단점
복잡성 : 클래스 계층 구조가 복잡해질 수 있습니다.
성능 오버헤드 : 가상 함수 테이블을 통한 호출로 인해 약간의 성능 저하가 있을 수 있습니다.
디자인 시간 : 적절한 추상화 수준을 결정하는 데 시간이 걸릴 수 있습니다.
추상 클래스 vs 인터페이스
앞서 언급했듯 C++에는 Java나 C#과 같은 별도의 interface 키워드가 없지만, 순수 가상 함수만을 포함하는 추상 클래스를 통해 인터페이스와 유사한 개념을 구현할 수 있습니다.
추상 클래스
일부 구현을 포함할 수 있음
생성자를 가질 수 있음
멤버 변수를 가질 수 있음
다중 상속 시 주의가 필요함
인터페이스 (순수 가상 함수만을 포함하는 추상 클래스)
구현을 포함하지 않음 (C++ 20 이전)
주로 다중 상속에 사용됨
멤버 변수를 가질 수 없음 (상수는 가능)
C++ 20의 컨셉과 추상 클래스
C++ 20에서 도입된 컨셉(Concepts)은 템플릿 매개변수에 대한 제약을 정의하는 새로운 방법을 제공합니다.
이는 추상 클래스와 유사한 역할을 하지만, 컴파일 타임에 작동합니다.
컨셉은 추상 클래스와 달리 런타임 다형성을 제공하지 않지만, 컴파일 타임에 타입 체크를 수행하여 더 빠른 코드를 생성할 수 있습니다.
실습 : 게임 캐릭터 시스템 설계
다음 요구사항을 만족하는 게임 캐릭터 시스템을 설계하고 구현해보세요.
Character를 추상 기본 클래스로 정의
Warrior, Mage, Archer 등의 구체적인 캐릭터 클래스 구현
Attackable, Healable 인터페이스 정의 및 구현
GameEngine 클래스를 만들어 여러 캐릭터를 관리하고 상호작용할 수 있도록 구현
이 실습을 통해 추상 클래스와 순수 가상 함수를 사용하여 게임 캐릭터 시스템을 설계하고 구현해보았습니다. 이러한 접근 방식은 새로운 캐릭터 유형을 쉽게 추가할 수 있게 해주며, 다형성을 활용하여 캐릭터들을 일관된 방식으로 다룰 수 있게 합니다.
연습 문제
Vehicle이라는 추상 기본 클래스를 만들고, Car, Motorcycle, Truck 등의 구체적인 차량 클래스를 구현해보세요. 각 클래스는 적절한 메서드(예 : start(), stop(), accelerate())를 가져야 합니다.
파일 시스템을 모델링하는 클래스 계층 구조를 설계해보세요. FileSystemItem을 추상 기본 클래스로 하고, File과 Directory 클래스를 구현하세요. 적절한 메서드(예 : getName(), getSize(), listContents())를 포함해야 합니다.
은행 계좌 시스템을 구현해보세요. Account를 추상 기본 클래스로 하고, SavingsAccount, CheckingAccount, InvestmentAccount 등의 구체적인 계좌 클래스를 만드세요. 각 클래스는 적절한 메서드(예 : deposit(), withdraw(), calculateInterest())를 가져야 합니다.
참고자료
Stroustrup, Bjarne. "The C++ Programming Language (4th Edition)"
Meyers, Scott. "Effective C++ : 55 Specific Ways to Improve Your Programs and Designs"
Gamma, Erich, et al. "Design Patterns : Elements of Reusable Object-Oriented Software"