. () , . , , - . , , . .. , , , . , , (. $$6.6.1). , - : void manager::print() const { employee::print(); // // } , :: , print() manager. ++. : void manager::print() const { print(); // // } manager::print(). 6.2.2  . , , : class employee { // ... public: // ... employee(char* n, int d); }; class manager : public employee { // ... public: // ... manager(char* n, int i, int d); }; . , : manager::manager(char* n, int l, int d) : employee(n,d), level(l), group(0) { } employee::employee() : employee::employee(char* n, int d) : name(n), department(d) { next = list; list = this; } list employee. : , , , . : , , . , . 6.2.3  : class employee { /* ... */ }; class manager : public employee { /* ... */ }; class director : public manager { /* ... */ }; . , : class temporary { /* ... */ }; class secretary : public employee { /* ... */ }; class tsec : public temporary, public secretary { /* ... */ }; class consultant : public temporary, public manager { /* ... */ }; , ++ ( $$6.5.3). : 6.2.4  , : , base*? : [1] , ($$6.4.2); [2] , ; [3] ($$6.2.5). (, , ..). [1] , .. . [2] [3] , .. ( , ). [3] - [2]. [1] [3]; 8. , .. [2]. manager/employee : struct employee { enum empl_type { M, E }; empl_type type; employee* next; char* name; short department; // ... }; struct manager : employee { employee* group; short level; // ... }; , , : void print_employee(const employee* e) { switch (e->type) { case E: cout << e->name << '\t' << e->department << '\n'; // ... break; case M: cout << e->name << '\t' << e->department << '\n'; // ... manager* p = (manager*) e; cout << "level" << p->level << '\n'; // ... break; } } : void f(const employee* elist) { for (; elist; elist=elist->next) print_employee(elist); } , , , : , . . - . - . , , , , - . , print() , : void print(const employee* e) { cout << e->name << '\t' << e->department << '\n'; // ... if (e->type == M) { manager* p = (manager*) e; cout << "level" << p->level << '\n'; // ... } } if, , , . , , . , , .. , . , . , . , . , , , , . 6.2.5  , . , . : class employee { char* name; short department; // ... employee* next; static employee* list; public: employee(char* n, int d); // ... static void print_list(); virtual void print() const; }; virtual () , print() , print() - . . , ( , . $$6.3). : void employee::print() const { cout << name << '\t' << department << '\n'; // ... } , , . , . , : class manager : public employee { employee* group; short level; // ... public: manager(char* n, int d); // ... void print() const; }; print_employee() - print(), . employee ($$6.2.2). : void employee::print_list() { for ( employee* p = list; p; p=p->next) p->print(); } . int main() { employee e("J.Brown",1234); manager m("J.Smith",2,1234); employee::print_list(); } J.Smith 1234 level 2 J.Brown 1234 , , employee_list() , manager! , employee . , . , , . , . , , . ::, , manager::print(), . . : ( ), :: . , , . - manager::print(). manager::print(), employee::print(), . 6.3  employee , . , . , , shape, (), . shape . , shape: class shape { // ... public: virtual void rotate(int) { error("shape::rotate"); } virtual void draw() { error("shape::draw"): } // , // ... }; shape ( ) , : shape s; // : `` '' , s . shape . , = 0: class shape { // ... public: virtual void rotate(int) = 0; // virtual void draw() = 0; // }; , , . : shape s; // : shape : class circle : public shape { int radius; public: void rotate(int) { } // : // shape::rotate void draw(); // : // shape::draw circle(point p, int r); }; , , . : class X { public: virtual void f() = 0; virtual void g() = 0; }; X b; // : X class Y : public X { void f(); // X::f }; Y b; // : Y class Z : public Y { void g(); // X::g }; Z c; // - . , : class character_device { public: virtual int open() = 0; virtual int close(const char*) = 0; virtual int read(const char*, int) =0; virtual int write(const char*, int) = 0; virtual int ioctl(int ...) = 0; // ... }; character_device. , . 6.4  . : [1] : ; , , ; [2] : (, , ) ; [3] : , , . , , . , , , , . . , , . , , , . , . 6.4.1  , . , : , ( -, , ..), , .. , , ++, . put_point() put_line(). point: // screen.h const int XMAX=40; const int YMAX=24; struct point { int x, y; point() { } point(int a,int b) { x=; y=b; } }; extern void put_point(int a, int b); inline void put_point(point p) { put_point(p.x,p.y); } extern void put_line(int, int, int, int); extern void put_line(point a, point b) { put_line(a.x,a.y,b.x,b.y); } extern void screen_init(); extern void screen_destroy(); extern void screen_refresh(); extern void screen_clear(); #include <iostream.h> , (put_...), screen_init(). , , screen_refresh(). , , . : #include "screen.h" #include <stream.h> enum color { black='*', white=' ' }; char screen[XMAX] [YMAX]; void screen_init() { for (int y=0; y<YMAX; y++) for (int x=0; x<XMAX; x++) screen[x] [y] = white; } void screen_destroy() { } . . , : inline int on_screen(int a, int b) // { return 0<=a && a <XMAX && 0<=b && b<YMAX; } void put_point(int a, int b) { if (on_screen(a,b)) screen[a] [b] = black; } put_line(): void put_line(int x0, int y0, int x1, int y1) /* (x0,y0) - (x1,y1). : b(x-x0) + a(y-y0) = 0. abs(eps), eps = 2*(b(x-x0)) + a(y-y0). . Newman, Sproull ``Principles of interactive Computer Graphics'' McGraw-Hill, New York, 1979. pp. 33-34. */ { register int dx = 1; int a = x1 - x0; if (a < 0) dx = -1, a = -a; register int dy = 1; int b = y1 - y0; if (b < 0) dy = -1, b = -b; int two_a = 2*a; int two_b = 2*b; int xcrit = -b + two_a; register int eps = 0; for (;;) { put_point(x0,y0); if (x0==x1 && y0==y1) break; if (eps <= xcrit) x0 +=dx, eps +=two_b; if (eps>=a || a<b) y0 +=dy, eps -=two_a; } } : void screen_clear() { screen_init(); } void screen_refresh() { for (int y=YMAX-1; 0<=y; y--) { // for (int x=0; x<XMAX; x++) // cout << screen[x] [y]; cout << '\n'; } } , , . 6.4.2  . , ( shape) , (, ..). , shape: struct shape { static shape* list; shape* next; shape() { next = list; list = this; } virtual point north() const = 0; virtual point south() const = 0; virtual point east() const = 0; virtual point west() const = 0; virtual point neast() const = 0; virtual point seast() const = 0; virtual point nwest() const = 0; virtual point swest() const = 0; virtual void draw() = 0; virtual void move(int, int) = 0; }; draw(), move(). , . : north - , ... , neast - -, ... , swest - -. , . shape::shape() shape::list. next, shape. , shape . . , . , , .. : class line : public shape { /* ["w", "e" ] north() - `` , '' */ point w, e; public: point north() const { return point((w.x+e.x)/2,e.y<w.y?w.y:e:y); } point south() const { return point((w.x+e.x)/2,e.y<w.y?e.y:w.y); } point east() const; point west() const; point neast() const; point seast() const; point nwest() const; point swest() const; void move(int a, int b) { w.x +=a; w.y +=b; e.x +=a; e.y +=b; } void draw() { put_line(w,e); } line(point a, point b) { w = a; e = b; } line(point a, int l) { w = point(a.x+l-1,a.y); e = a; } }; : class rectangle : public shape { /* nw ------ n ----- ne | | | | w c e | | | | sw ------ s ----- se */ point sw, ne; public: point north() const { return point((sw.x+ne.x)/2,ne.y); } point south() const { return point((sw.x+ne.x)/2,sw.y); } point east() const; point west() const; point neast() const { return ne; } point seast() const; point nwest() const; point swest() const { return sw; } void move(int a, int b) { sw.x+=a; sw.y+=b; ne.x+=a; ne.y+=b; } void draw(); rectangle(point,point); }; . , : rectangle::rectangle(point a, point b) { if (a.x <= b.x) { if (a.y <= b.y) { sw = a; ne = b; } else { sw = point(a.x,b.y); ne = point(b.x,a.y); } } else { if (a.y <= b.y) { sw = point(b.x,a.y); ne = point(a.x,b.y); } else { sw = b; ne = a; } } } , : void rectangle::draw() { point nw(sw.x,ne.y); point se(ne.x,sw.y); put_line(nw,ne); put_line(ne,se); put_line(se,sw); put_line(sw,nw); } : void shape_refresh(); // void stack(shape* p, const shape* q); // p q , ; . , , : void shape_refresh() { screen_clear(); for (shape* p = shape::list; p; p=p->next) p->draw(); screen_refresh(); } , , . (south()) (north()) : void stack(shape* p, const shape* q) // p q { point n = q->north(); point s = p->south(); p->move(n.x-s.x,n.y-s.y+1); } , , , , . , . 6.4.3  . myshape ( , ), main(), . myshape: #include "shape.h" class myshape : public rectangle { line* l_eye; // line* r_eye; // line* mouth; // public: myshape(point, point); void draw(); void move(int, int); }; myshape: myshape::myshape(point a, point b) : rectangle(a,b) { int ll = neast().x-swest().x+1; int hh = neast().y-swest().y+1; l_eye = new line( point(swest().x+2,swest().y+hh*3/4),2); r_eye = new line( point(swest().x+ll-4,swest().y+hh*3/4),2); mouth = new line( point(swest().x+2,swest().y+hh/4),ll-4); } , , shape_refresh() . my_shape, . myshape. , . "" , draw(): void myshape::draw() { rectangle::draw(); int a = (swest().x+neast().x)/2; int b = (swest().y+neast().y)/2; put_point(point(a,b)); } myshape rectangle (l_eye, r_eye mouth): void myshape::move(int a, int b) { rectangle::move(a,b); l_eye->move(a,b); r_eye->move(a,b); mouth->move(a,b); } , : int main() { screen_init(); shape* p1 = new rectangle(point(0,0),point(10,10)); shape* p2 = new line(point(0,15),17); shape* p3 = new myshape(point(15,10),point(27,18)); shape_refresh(); p3->move(-10,-10); stack(p2,p3); stack(p1,p2); shape_refresh(); screen_destroy(); return 0; } , , shape_refresh() stack(), , (, , ). : *********** * * * * * * * * * * * * * * *********** ***************** *********** * * * ** ** * * * * * * * * * ******* * * * *********** . 6.5  $$1.5.3 $$6.2.3 , . , : . , task, displayed. ( satellite) : class satellite : public task, public displayed { // ... }; . , . satellite task displayed: void f(satellite& s) { s.draw(); // displayed::draw() s.delay(10); // task::delay() s.xmit(); // satellite::xmit() } , satellite task displayed: void highlight(displayed*); void suspend(task*); void g(satellite* p) { highlight(p); // highlight((displayed*)p) suspend(p); // suspend((task*)p); } , () : task displayed satellite. , , : class task { // ... virtual pending() = 0; }; class displayed { // ... virtual void draw() = 0; }; class satellite : public task, public displayed { // ... void pending(); void draw(); }; satellite::draw() satellite::pending() satellite , displayed task, . , displayed, task satellite. satellite task displayed, (, , task displayed ). . 6.5.1  . , task displayed link, satellite : class task : public link { // link // ( ) // ... }; class displayed : public link { // link // ( ) // ... }; . link , . , link, , . satellite : , (. $$6.5.3). 6.5.2  , - : class task { // ... virtual debug_info* get_debug(); }; class displayed { // ... virtual debug_info* get_debug(); }; satellite : void f(satellite* sp) { debug_info* dip = sp->get_debug(); //: dip = sp->task::get_debug(); // dip = sp->displayed::get_debug(); // } , , : class satellite : public task, public derived { // ... debug_info* get_debug() { debug_info* dip1 = task:get_debug(); debug_info* dip2 = displayed::get_debug(); return dip1->merge(dip2); } }; satellite . satellite::get_debug() get_debug() , , get_debug() satellite. , , . , , . . , , , . , , , $$13.8 draw() Window Cowboy. , . , , "- ". (, ), . , $$6.2.5 void manager::print() { employee::print(); // ... } , employee - manager. , employee manager, print() . , - : class employee { // ... virtual void print(); }; class foreman : public employee { // ... void print(); }; class manager : public foreman { // ... void print(); }; foreman::print() , . : class foreman : public employee { typedef employee inherited; // ... void print(); }; class manager : public foreman { typedef foreman inherited; // ... void print(); }; void manager::print() { inherited::print(); // ... } , , , , inherited . - , inherited . 6.5.3  , . , , ( ), . , "" . - . , , . . (. $$13.2 $$8.7). - . ++ - , , . . "" , : class window { // virtual void draw(); }; window - draw(). , (window). ( ) (draw): class window_w_border : public virtual window { // " " // , void draw(); }; class window_w_menu : public virtual window { // " " // , void draw(); }; : class window_w_border_and_menu : public virtual window, public window_w_border, public window_w_menu { // " " void draw(); }; . , , window window .