piste.cpp - esimerkki perinnästä#include <stdio.h> // Esimerkki ehdollisesta kaantamisesta: #define RTTI // RTTI = Run Time Type Information, // toimii esim. BC++ 4.5 alkaen #ifdef RTTI #include <typeinfo.h> #endif //------------------------------------------- class caGraafinenOlio { protected: int x,y; int nakyy; int paikka(int nx,int ny) { x = nx; y = ny; return 0; } public: caGraafinenOlio(int ix=0, int iy=0) { paikka(ix,iy); nakyy = 0; } virtual ~caGraafinenOlio() { } virtual int piirra() const = 0; int nakyvissa() const { return nakyy; } int sammuta(); int sytyta(); int siirra(int nx, int ny) { if ( !nakyvissa() ) return paikka(nx,ny); sammuta(); paikka(nx,ny); return sytyta(); } virtual int tulosta(const char *s="") const { # ifdef RTTI printf("%-10s: ",typeid(*this).name()); # endif printf("%-10s (%02d,%02d)",s,x,y); return 0; } }; // caGraafinen olio int caGraafinenOlio::sammuta() { if ( !nakyvissa() ) return 1; printf("Sammutettu: "); nakyy = 0; return piirra(); } int caGraafinenOlio::sytyta() { if ( nakyvissa() ) return 1; printf("Sytytetty: "); nakyy = 1; return piirra(); } //------------------------------------------- class caSateellinenOlio : public caGraafinenOlio { protected: int r; int koko(int nr) { r = nr; return 0; } public: caSateellinenOlio(int ix=0,int iy=0, int ir=1) : caGraafinenOlio(ix,iy), r(ir) {} virtual int tulosta(const char *s="") const { caGraafinenOlio::tulosta(s); printf( " r=%d",r); return 0; } int muuta_koko(int nr) { if ( !nakyvissa() ) return koko(nr); sammuta(); koko(nr); return sytyta(); } }; // caSateellinen olio //------------------------------------------- class cPiste : public caGraafinenOlio { public: cPiste(int ix=0, int iy=0) : caGraafinenOlio(ix,iy) {} virtual ~cPiste() { sammuta(); } virtual int piirra() const { tulosta("Piste"); printf("\n"); return 0;} }; //------------------------------------------- class cYmpyra : public caSateellinenOlio { public: cYmpyra(int ix=0, int iy=0, int ir=1) : caSateellinenOlio(ix,iy,ir) {} virtual ~cYmpyra() { sammuta(); } virtual int piirra() const { tulosta("Ympyra"); printf("\n"); return 0;} }; int main(void) { caGraafinenOlio *p; caGraafinenOlio *kuvat[10]; int i; cPiste p1,p2(10,20); cYmpyra y1(1,1,2); p1.sytyta(); p2.sytyta(); p1.siirra(7,8); y1.sytyta(); y1.muuta_koko(5); // Esimerkki polymorfismista p = new cYmpyra(9,9,9); p->sytyta(); p->siirra(8,8); // p->muuta_koko(4); ei laillinen # ifdef RTTI // if ( typeid(*p) == typeid(cYmpyra) ) caSateellinenOlio *ps = dynamic_cast<caSateellinenOlio *>(p); if ( ps ) ps->muuta_koko(4); # else ((caSateellinenOlio *)p)->muuta_koko(4); # endif delete p; // Esimerkki polymorfismista kuvat[0] = new cYmpyra(10,10,100); kuvat[1] = new cPiste(11,11); kuvat[2] = new cYmpyra(12,12,102); kuvat[3] = NULL; for (i=0; kuvat[i];i++) kuvat[i]->sytyta(); for (i=0; kuvat[i];i++) delete kuvat[i]; return 0; } |
piste.dpr - esimerkki perinnästäprogram piste; { Esimerkki ehdollisesta kaantamisesta: } {$DEFINE RTTI } uses WinCRT,SysUtils; {-------------------------------------------} type caGraafinenOlio = class protected x,y:integer; nakyy:boolean; procedure paikka(nx,ny:integer); public constructor Create; constructor Create2(ix,iy:integer); destructor Destroy; override; procedure piirra; virtual; abstract; function nakyvissa:boolean; procedure sammuta; procedure sytyta; procedure siirra(nx,ny:integer); procedure tulosta(s:string); virtual; end; procedure caGraafinenOlio.paikka( nx,ny:integer); begin x := nx; y := ny; end; constructor caGraafinenOlio.Create2( ix,iy:integer); begin inherited Create; paikka(ix,iy); nakyy := False; end; constructor caGraafinenOlio.Create; begin Create2(0,0); end; destructor caGraafinenOlio.Destroy; begin sammuta; inherited Destroy; end; function caGraafinenOlio.nakyvissa:boolean; begin Result := nakyy; end; procedure caGraafinenOlio.siirra( nx,ny:integer); begin if ( not nakyvissa ) then begin paikka(nx,ny); exit; end; sammuta; paikka(nx,ny); sytyta; end; procedure caGraafinenOlio.tulosta(s:string); begin {$IFDEF RTTI} write(format('%-10s: ',[ClassName])); {$ENDIF} write(format('%-10s (%02d,%02d)',[s,x,y])); end; procedure caGraafinenOlio.sammuta; begin if ( not nakyvissa ) then exit; write('Sammutettu: '); nakyy := False; piirra; end; procedure caGraafinenOlio.sytyta; begin if ( nakyvissa ) then exit; write('Sytytetty: '); nakyy := True; piirra; end; {-------------------------------------------} type caSateellinenOlio = class(caGraafinenOlio) protected r:integer; procedure koko(nr:integer); public constructor Create3(ix,iy,ir:integer); constructor Create2(ix,iy:integer); constructor Create; procedure tulosta(s:string); override; procedure muuta_koko(nr:integer); end; procedure caSateellinenOlio.koko(nr:integer); begin r := nr; end; constructor caSateellinenOlio.Create3( ix,iy,ir:integer); begin inherited Create2(ix,iy); koko(ir); end; constructor caSateellinenOlio.Create2( ix,iy:integer); begin Create3(ix,iy,1); end; constructor caSateellinenOlio.Create; begin inherited Create; koko(1); end; procedure caSateellinenOlio.tulosta(s:string); begin inherited tulosta(s); write(' r=',r); end; procedure caSateellinenOlio.muuta_koko( nr:integer); begin if ( not nakyvissa ) then begin koko(nr); exit; end; sammuta; koko(nr); sytyta; end; {-------------------------------------------} type cPiste = class(caGraafinenOlio) public procedure piirra; override; end; procedure cPiste.piirra; begin tulosta('Piste'); writeln; end; {-------------------------------------------} type cYmpyra = class(caSateellinenOlio) public procedure piirra; override; end; procedure cYmpyra.piirra; begin tulosta('Ympyra'); writeln; end; {-------------------------------------------} var p : caGraafinenOlio; kuvat : array[0..9] of caGraafinenOlio; p1,p2 : cPiste; y1 : cYmpyra; i : integer; begin p1 := cPiste.Create; p2 := cPiste.Create2(10,20); y1 := cYmpyra.Create3(1,1,2); p1.sytyta; p2.sytyta; p1.siirra(7,8); y1.sytyta; y1.muuta_koko(5); (* Esimerkki polymorfismista *) p := cYmpyra.Create3(9,9,9); p.sytyta; p.siirra(8,8); { p.muuta_koko(4); ei laillinen } {$IFDEF RTTI } if ( p is caSateellinenOlio ) then {$ENDIF} (p as caSateellinenOlio).muuta_koko(4); p.Free; (* Esimerkki polymorfismista *) kuvat[0] := cYmpyra.Create3(10,10,100); kuvat[1] := cPiste.Create2(11,11); kuvat[2] := cYmpyra.Create3(12,12,102); kuvat[3] := NIL; i:=0; while ( kuvat[i] <> NIL ) do begin kuvat[i].sytyta; inc(i); end; i:=0; while ( kuvat[i] <> NIL ) do begin kuvat[i].Free; inc(i); end; y1.Free; p2.Free; p1.Free; end. |
Mikäli vakio RTTI on määritelty, tulostavat molemmat ohjelmat:
Sytytetty: cPiste : Piste ( 0, 0) Sytytetty: cPiste : Piste (10,20) Sammutettu: cPiste : Piste ( 0, 0) Sytytetty: cPiste : Piste ( 7, 8) Sytytetty: cYmpyra : Ympyra ( 1, 1) r=2 Sammutettu: cYmpyra : Ympyra ( 1, 1) r=2 Sytytetty: cYmpyra : Ympyra ( 1, 1) r=5 Sytytetty: cYmpyra : Ympyra ( 9, 9) r=9 Sammutettu: cYmpyra : Ympyra ( 9, 9) r=9 Sytytetty: cYmpyra : Ympyra ( 8, 8) r=9 Sammutettu: cYmpyra : Ympyra ( 8, 8) r=9 Sytytetty: cYmpyra : Ympyra ( 8, 8) r=4 Sammutettu: cYmpyra : Ympyra ( 8, 8) r=4 Sytytetty: cYmpyra : Ympyra (10,10) r=100 Sytytetty: cPiste : Piste (11,11) Sytytetty: cYmpyra : Ympyra (12,12) r=102 Sammutettu: cYmpyra : Ympyra (10,10) r=100 Sammutettu: cPiste : Piste (11,11) Sammutettu: cYmpyra : Ympyra (12,12) r=102 Sammutettu: cYmpyra : Ympyra ( 1, 1) r=5 Sammutettu: cPiste : Piste (10,20) Sammutettu: cPiste : Piste ( 7, 8)Jos vakiota RTTI ei ole määritelty, on tulostus muuten sama, mutta puuttuu sarake, jossa on cPiste ja cYmpyra.
Delphissä on kaksi tapaa tehdä luokkia:
// Vertaa: int siirra(int nx, int ny) { if ( !nakyvissa() ) return paikka(nx,ny); sammuta(); paikka(nx,ny); return sytyta(); } // Tai: void siirra(int nx, int ny) { if ( !nakyvissa() ) { paikka(nx,ny); return; } sammuta(); paikka(nx,ny); sytyta(); }
{ Vertaa: } function caGraafinenOlio.siirra(nx,ny:integer):integer; begin if ( not nakyvissa ) then begin siirra := paikka(nx,ny); exit; end; sammuta; paikka(nx,ny); siirra := sytyta; end; { Tai: } procedure caGraafinenOlio.siirra(nx,ny:integer); begin if ( not nakyvissa ) then begin paikka(nx,ny); exit; end; sammuta; paikka(nx,ny); sytyta; end;