画面上の点を定義したので,今度は画面上の線を定義してみよう.
class Line { protected: vector2D p1; //始点 vector2D p2; //終点 int color; public: Line(int x1, int y1, int x2; int y2, int col) { p1.x = x1; p1.y = y1; p2.x = x2; p2.y = y2; color = col; draw_line(x1,y1,x2,y2,color); } .... void move_to(int x, int y) { ... } };
Line::move_to()
は,線の始点を(x,y)に移動する関数だと
思ってほしい.
さて,MacDrawのようなグラフィックエディタを考えてみよう. このようなソフトでは,線・点などの図形を自由に移動したり 拡大・縮小したりできる.こんなときに,こういうクラスの定義をして おくと,何かと便利だ.
class GraphicObject { public: virtual void move_to(int,int) = 0; }; class Point : public GraphicObject { .... void move_to(int,int); }; class Line : public GraphicObject { .... void move_to(int,int); };
GraphicObjectというクラスは,その下にあるPointやLine (や,この後作られるであろうRectancle, PolyLine, Ellipseなど) をひとまとめにして使うためのクラスで,それ自体はインスタンスを持たない. このようなクラスを抽象クラスと呼ぶ.
GraphicObjectを使った場合,前の方で出てきたMovingPointと
AccelPointのように,同じポインタに対してmove_to()
を呼ぶことで,それぞれの図形にあった動作をしてくれるというわけだ.
そのため,GraphicObjectはメンバ関数move_to()
を
仮想関数として持たなければならないが,GraphicObject自体は
特定の図形ではないので,GraphicObject::move_to()
を
定義することはできない.そこで,クラスGraphicObjectでは
関数の名前だけ定義して,その実装は派生クラスにまかせている.
これが
という記述だ.このような関数を純粋仮想関数という.class GraphicObject { public: virtual void move_to(int,int) = 0; };