抽象クラス
次のような、簡単なクラスを作るものとします。
※ '-' で描く横線クラス … HorzLine
※ '|' で描く縦線クラス … VertLine
※ '*' で描く四角形クラス … Rectangle
これらはすべて、図形ですから、まず具体的な個々の形には踏み込まずに、抽象的な
図形クラス … Shape
を作成することにします。
とは言っても、図形というだけでは、形に関してはまだ何もわかりません。ひとつ確かなことは、図形なら、"描く"作業が必ず必要なはずです。
そこで、次のようなクラスを作ってみます。draw関数は、"描く"ための関数(関数の中身は空っぽですが)です。
class Shape {
public:
virtual void draw() = 0 ;
// " = 0 " は 純粋指定子
// この純粋指定子を付けて宣言された
// 仮想関数は、 純粋仮想関数 となりま
// す。
};
【 抽象クラス 】
クラス Shape には具体的な情報が含まれていないので、Shape型のオブジェクトを作ることは不可能です。
この Shape のようなクラスは 抽象クラスと呼ばれ、 具体的な図形クラスは、このクラスからの派生で実現する ようにします。
次のプログラムでは、抽象クラス Shape から派生した Rectangleクラスの長方形オブジェクト a, b を生成して、それぞれのオブジェクトの draw関数で長方形を描いています。
// ------------------------------------
#include <iostream>
// 抽象クラス Shape
class Shape {
public:
virtual ~Shape() = 0;
// 純粋仮想デストラクタ
virtual void draw() const = 0 ;
// 描画
// 純粋仮想関数
};
inline Shape::~Shape() { }
// 長方形クラス Rectangle
// ( 抽象クラス Shape から派生 )
class Rectangle : public Shape {
int width; // 横幅
int height; // 高さ
public:
Rectangle(int w, int h)
: width(w), height(h) { }
void draw() const {
for (int i = 1; i <= height; i++) {
for (int j = 1; j <= width; j++)
std::cout << '*';
std::cout << '\n';
}
}
};
int main() {
Rectangle a(5, 3);
Rectangle b(3, 4);
Shape& ref = b;
// Rectangle& ref = b; としても結果は同じで
// すが、図形の種類が増えてきて、様々な
// 処理をしなけらばならなくなったときの
// 効率を考えれば、Shape& とすべきです。
a.draw();
std::cout << '\n';
ref.draw();
}
// ------------------------------------