// circle.cpp, esimerkki perinnasta ja luokista/vl-96 // Todellisen piirt„misen sijasta tulostetaan n„ytt””n keskipiste & koko // tulosta-metodi on vain t„t„ tarkoitusta varten! #include // Esimerkki ehdollisesta kaantamisesta: #define RTTI // RTTI = Run Time Type Information, // toimii esim. BC++ 4.5 alkaen #ifdef RTTI #include #endif //---------------------------------------------------------------------------- class caKuvio { int nakyy; // Sytytetty vai sammutettu void vaihda_paikka(int nx,int ny) { x = nx; y = ny; } protected: // Jos halutaan peri„ luokkaa, pit„„ j„lkel„isten int x,y; // k„ytt””n sallittujen attrib. olla protected public: caKuvio(int ix=0, int iy=0) { vaihda_paikka(ix,iy); nakyy = 0; } virtual ~caKuvio() { sammuta(); } int nakyvissa() const { return nakyy; } virtual void piirra() const = 0; // Pure virtual-metodi => abstr. luokka void sammuta() { if ( nakyvissa() ) { nakyy = 0; piirra(); }} void sytyta() { if ( !nakyvissa() ) { nakyy = 1; piirra(); }} void siirra(int nx, int ny) { if ( !nakyvissa() ) { vaihda_paikka(nx,ny); return; } sammuta(); vaihda_paikka(nx,ny); sytyta(); } virtual void tulosta(const char *s="") const { printf("%-10s: %-10s (%02d,%02d)",nakyy?"Sytytetty":"Sammutettu",s,x,y); } }; // caKuvio //---------------------------------------------------------------------------- class caKuvioJollaSade : public caKuvio { int koko(int nr) { r = nr; return 0; } protected: int r; // Uusi atribuutti, koko public: caKuvioJollaSade(int ix=0,int iy=0,int ir=1) : caKuvio(ix,iy), r(ir) {} void muuta_koko(int nr) { // Uutena ominaisuutena koon muuttaminen if ( !nakyvissa() ) { koko(nr); return; } sammuta(); koko(nr); sytyta(); } virtual void tulosta(const char *s="") const { caKuvio::tulosta(s); printf( " r=%d",r); } }; // caKuvioJollaSade //---------------------------------------------------------------------------- class cPiste : public caKuvio { public: cPiste(int ix=0, int iy=0) : caKuvio(ix,iy) {} virtual ~cPiste() { sammuta(); } virtual void piirra() const { tulosta("Piste"); printf("\n"); } }; // cPiste //---------------------------------------------------------------------------- class cYmpyra : public caKuvioJollaSade { public: cYmpyra(int ix=0, int iy=0, int ir=1) : caKuvioJollaSade(ix,iy,ir) {} virtual ~cYmpyra() { sammuta(); } virtual void piirra() const { tulosta("Ympyra"); printf("\n"); } }; // cYmpyra //---------------------------------------------------------------------------- int main(void) { { printf("-------------------------------------------------\n"); caKuvio *p; p = new cYmpyra(11,12,13); p->sytyta(); delete p; } { printf("-------------------------------------------------\n"); caKuvio *p; cPiste a(7,2),b; cYmpyra y(5,4,12); y.sytyta(); b = a; // OK! //a = y; // Ei toimi, jollei ole kunstruktoria cPiste(cYmpyra) p = &a; // OK! T„ll„ voidaan kiert„„ edellinen! *p = y; // "a = y". Pisteelle ympyr„n keskipiste ja n„kyy. //y = b; // Ei toimi, jollei ole konstruktoria cYmpyra(cPiste); p = &y; // OK! => y = b *p = b; // Sijoistus laillinen koska caKuviosytyta(); p->piirra(); ((cYmpyra *)p)->muuta_koko(5); # ifdef RTTI if ( typeid(*p) == typeid(cYmpyra) ) printf("Samoja ovat!\n"); caKuvioJollaSade *ps = dynamic_cast(p); if ( ps ) ps->muuta_koko(4); #else ((caKuvioJollaSade *)p)->muuta_koko(4); # endif return 0; } }