class Shape {
public:
virtual void Draw() = 0;
};
class Rect : public Shape {
public:
virtual void Draw() { } // 구현
};
int main() {
Shape s; // error
Shape* p; // ok
Rect r; // 구현부가 있으므로 ok
}
순수 가상 함수 (pure virtual function)
→ 함수의 구현부가 없고, 선언부가 =0 으로 끝나는 가상함수
추상 클래스 (Abstract Class)
→ 순수 가상 함수가 한 개 이상 있는 클래스
추상 클래스 특징
→ 객체를 생성할 수 없다
→ 포인터 변수를 만들 수 있다.
추상 클래스로부터 파생된 클래스
→ 기반 클래스의 순수 가상
추상 클래스의 설계 의도
→ 파생 클래스에게 특정 멤버 함수를 반드시 만들어야 한다고 지시하는 것
#include <iostream>
#include <vector>
using namespace std;
class Shape {
public:
virtual void Draw() { cout << "Shape::Draw" << endl; }
};
class Rect : public Shape {
public:
virtual void Draw() { cout << "Rect::Draw" << endl; }
};
class Circle : public Shape {
public:
virtual void Draw() { cout << "Circle::Draw" << endl; }
};
int main() {
vector<Shape*> v;
while (1) {
int cmd;
cin >> cmd;
if ( cmd == 1 ) v.push_back( new Rect );
else if ( cmd == 2 ) v.push_back( new Circle );
else if (cmd == 9 ) {
for ( auto p : v ) // p 는 Shape* 타입
p->Draw();
}
}
}
모든 도형을 Class 타입으로 설계한다.
→ Rect, Circle 클래스 설계
모든 도형의 공통의 기반 클래스가 있다면, 하나의 컨테이너에 묶어서 관리 할 수 있다.
→ Shape 클래스 도입
→ vector <Shape * >에 모든 도형 보관
모든 도형의 공통의 특징(Draw 함수)는 반드시 Shape에 있어야 한다.
→ Shape * 를 사용해서 Draw()를 호출할 수 있어야 한다.
위의 코드는 Shape를 기반 클래스로 필요한 도형을 모두 만들어 Draw를 선언하고 있음. 그런데 위에서 기반클래스인 Shape는 “도형”이라는 추상적인 존재이므로 그릴수 없다. 그래서 다시 만든다면
class Shape {
public:
virtual void Draw() {}
};