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;