가상 함수와 추상 클래스에 대한 정리
1. 가상함수 (Virtual Function)
- 선언: virtual void MakeSound( );
- 자식 클래스에서 해당 함수의 세부 구현을 제공하면 자식 클래스의 함수가 호출된다.
- 만약 자식클래스에서 구현하지 않았다면, 부모 클래스의 함수가 호출된다.
- 가상 함수는 다형성을 구현하는 데 사용된다.
- 다형성에서 부모클래스의 소멸자를 가상함수로 선언하지 않고 부모 클래스 포인터에서 자식 클래스의 소멸자를 호출하게 되면 부모 클래스의 소멸자만 호출되고 자식클래스의 소멸자는 호출되지 않아 메모리 누수가 발생할 수 있다.
- C++에서는 소멸자가 가상이 아니면, 정적 바인딩(static binding)으로 동작한다.
- 정적 바인딩은 컴파일 타임에 소멸자 호출이 결정되므로, 부모 클래스 포인터를 통해 객체를 삭제할 때, 해당 포인터가 가리키는 객체 타입은 부모 클래스로 간주된다.
2. 순수 가상 함수 (Pure Virtual Function)
- 선언: virtual void MakeSound( ) = 0;
- 순수 가상 함수는 함수의 구현 없이 선언만 존재한다.
- 자식 클래스는 반드시 이 함수를 구현해야 한다. 그렇지 않으면 Error 발생.
- 순수 가상 함수를 포함한 클래스는 추상 클래스가 된다.
3. 추상 클래스 (Abstract Class)
- 추상 클래스는 순수 가상 함수를 하나 이상 포함한 클래스를 말한다.
- 추상 클래스는 객체를 생성할 수 없다. (변수로 선언 불가)
- 추상 클래스는 다른 클래스의 기반 클래스로 사용되어, 공통 기능을 정의하거나 자식 클래스가 반드시 구현해야 할 인터페이스를 제공하는 역할을 한다고 보면 된다.
// 부모 클래스: 추상 클래스
class Animal {
public:
virtual void MakeSound() = 0; // 순수 가상 함수
virtual void Move() {
cout << "Animal moves!" << endl; // 일반 가상 함수
}
};
// 자식 클래스: 추상 클래스의 구현
class Dog : public Animal {
public:
void MakeSound() override {
cout << "Dog barks!" << endl; // 순수 가상 함수 구현
}
void Move() override {
cout << "Dog runs!" << endl; // 가상 함수 재정의
}
};
int main() {
// Animal animal; // 오류: 추상 클래스는 객체 생성 불가
Dog dog;
dog.MakeSound(); // 출력: Dog barks!
dog.Move(); // 출력: Dog runs!
Animal* ptr = &dog;
ptr->MakeSound(); // 출력: Dog barks! (다형성)
ptr->Move(); // 출력: Dog runs!
return 0;
}
요약
- virtual void MakeSound();
- 가상 함수로, 자식 클래스에서 구현하지 않으면 부모 클래스의 함수가 호출됩니다.
- 자식 클래스에서 구현하면 자식 클래스의 함수가 호출됩니다.
- virtual void MakeSound() = 0;
- 순수 가상 함수로, 반드시 자식 클래스에서 구현해야 합니다.
- 이 함수가 포함된 클래스는 추상 클래스가 되며, 객체 생성이 불가능합니다.
'내배캠 > C++' 카테고리의 다른 글
스마트 포인터 (0) | 2024.12.24 |
---|---|
Stack / Static / Heap (2) | 2024.12.24 |
Quick Sort 정렬 알고리즘 (0) | 2024.12.23 |
유클리드 알고리즘 (1) | 2024.12.23 |
Class (0) | 2024.12.23 |