순수 가상 함수(pure virtual function)와 추상 클래스(abstract class)
이전 시간까지 가상 함수에 대해서 배웠다.
- 아래 예시와 같이 가상 함수를 통해 오버라이딩을 할 수 있었다.
#include <iostream>
using namespace std;
class A {
public:
virtual void f() {}
};
class B : public A {
public:
void f() {}
};
int main() {
A *a = new B;
a->f();
delete a;
}
순수 가상 함수란 무엇인가요?
- 가상이라는 것은 실제로는 존재하지 않는다는 의미인데, 이전 시간에서 다뤘듯 부모타입 포인터 변수가 부모타입 객체를 가리키면, 가상 함수 호출이 가능했다
- 그래서 완전히 존재하지 않는 함수로 만들어 주기 위해, 순수 가상 함수를 사용한다.
class A { // 추상클래스
public:
// 순수 가상함수
virtual void f() = 0; // 0 또는 NULL
};
순수 가상 함수를 포함하고 있는 클래스는 그 타입을 갖는 인스턴스를 만들 수 없다.
- 이러한 클래스를 추상 클래스라고 부른다
A *a = new A; // 에러 발생
- 자식 인스턴스를 생성하는 것은 가능하다.
int main() {
A *a = new B;
a->f();
delete a;
}
어떤 상황에서 순수 가상 함수를 사용하면 좋을까?
Example) 두 가지 도형 Circle, Rectangle이 있다고 해보자.
#include <iostream>
using namespace std;
const double PI = 3.1415;
class Circle {
public:
Circle(double r) : r(r) {}
double GetArea() {
return PI * r * r;
}
void Resize(double f) {
r *= f;
}
private:
double r;
};
class Rectangle {
public:
Rectangle(double a, double b) : a(a), b(b) {}
double GetArea() {
return a * b;
}
void Resize(double f) {
a *= f;
b *= f;
}
private:
double a, b;
};
- 두 클래스를 Shape라는 클래스에 한꺼번에 어딘가에 저장해주고 싶다.
Shape *shapes[] = {
new Circle(10),
new Rectangle(20, 30)
};
- Shape라는 클래스로 뽑아내보자
class Shape {
public:
virtual double GetArea() {
// 어떤 것을 리턴해야 할까?
}
virtual void Resize(double f) {
}
};
물론 shape의 GetArea()를 호출할 일은 없지만, 만약 실수를 해서 호출해버리게 된다면 virtual double GetArea()에서, 리턴해줄 것이 없다.
- 이런 경우를 대비해서, 순수 가상 함수로 선언하여 추상 클래스로 만들어준다 --> 인스턴스를 만드는 것을 방지
class Shape {
public:
virtual double GetArea() = 0;
virtual void Resize(double f) = 0;
};
- 이제, 여러 개의 도형을 for문을 통해서 다뤄보자
int main() {
Shape *shapes[] = {
new Circle(10),
new Rectangle(20, 30)};
for (Shape *s : shapes) {
s->Resize(2.0);
}
for (Shape *s : shapes) {
cout << s->GetArea() << endl;
}
for (Shape *s : shapes) {
delete s;
}
}
참조) 두들낙서 C/C++ 강좌
'Programming Language > C++' 카테고리의 다른 글
[C++] 상속에서의 형변환 - 업캐스팅(Upcasting) (0) | 2024.06.27 |
---|---|
[C++] 생성/소멸자 실행 순서와 가상 소멸자 (0) | 2024.06.27 |
[C++] 상속이 필요한 이유(2) (0) | 2024.06.27 |
[C++] 가상 함수(Virtual Function)와 동적 바인딩(Dynamic Binding) (0) | 2024.06.27 |
[C++] 오버라이딩(Overriding)과 정적 바인딩(Static Binding) (0) | 2024.06.27 |