Myöhäinen sidonta saadaan C++:ssa aikaan liittämällä virtual- avainsana metodien eteen. Kaikki ne metodit täytyy ilmoittaa myöhäiseen sidontaan, joita mahdolliset perilliset tulevat muuttamaan. Siis luokat vielä kerran remonttiin:
#include <iostream.h>
#include <iomanip.h>
class cAika {
int h,m;
public:
virtual void aseta(int ih,int im=0) { // lisätty virtual
h = ih; m = im; lisaa(0);
}
cAika(int ih=0, int im=0) { aseta(ih,im); }
virtual void lisaa(int lisa_min) { // lisätty virtual
int yht_min = h * 60 + m + lisa_min;
h = yht_min / 60;
m = yht_min % 60;
}
virtual void tulosta(int lf=1) const { // lisätty virtual
cout << setfill('0') << setw(2) << h << ":" << setw(2) << m;
if ( lf ) cout << endl;
}
};
class cAikaSek : public cAika {
int s;
public:
virtual void aseta(int ih=0, int im=0) { cAika::aseta(ih,im); } // lisätty
virtual void aseta(int ih, int im, int is) { // lisätty virtual
s = is; aseta(ih,im); lisaa(0,0); // pois cAika::
}
cAikaSek(int ih=0, int im=0, int is=0) { aseta(ih,im,is); }
virtual void lisaa(int lisa_min) { cAika::lisaa(lisa_min); } // lisätty
virtual void lisaa(int lisa_min, int lisa_sek) { // lisätty virtual
s += lisa_sek; lisaa(lisa_min+s/60); s %= 60; // pois cAika::
}
virtual void tulosta(int lf=1) const { // lisätty virtual
cAika::tulosta(0);
cout << ":" << setw(2) << s;
if ( lf ) cout << endl;
}
};
int main(void)
.. kuten aikacla8.cpp + cAika *pAika; ...
Virtual sanat on lisätty kaikkien metodien eteen. Aliluokassa
virtual on tarpeeton uudelleenmääriteltävien
(korvaaminen,
syrjäyttäminen,
overriding)
metodien kohdalle, mutta se on hyvä pitää siellä
kommenttimielessä. Sitten tuleekin hankalammin selitettävä asia. Miksi yksi- parametrinen lisaa ja kaksi- parametrinen aseta on täytynyt kirjoittaa uudelleen? Tämä johtuu kielen ominaisuuksista, sillä muuten vastaavat useampi- parametriset metodit syrjäyttäisivät alkuperäiset metodit ja alkuperäisiä ei olisi lainkaan käytössä. Tässä tapauksessa olisimmekin voineet antaa niiden syrjäytyä, mutta koska tulevaisuudesta ei koskaan tiedä, on alkuperäiselläkin parametrimäärällä olevien metodien ehkä hyvä säilyä.
Parempi ratkaisu olisi ehkä kuitenkin ollut, jos jo alkuperäisessä luokassa olisi varauduttu sekuntien tuloon, vaikka niitä ei olisi mitenkään otettukaan huomioon:
...
class cAika { // Muutokset aikacla8.cpp:hen verrattuna
int h,m;
public:
virtual void aseta(int ih=0,int im=0, int lisa_sek=0) { // virtual, lisa_sek
h = ih; m = im; lisaa(0);
}
cAika(int ih=0, int im=0) { aseta(ih,im); }
virtual void lisaa(int lisa_min, int lisa_sek=0) { // virtual, lisa_sek
int yht_min = h * 60 + m + lisa_min;
h = yht_min / 60;
m = yht_min % 60;
}
virtual void tulosta(int lf=1) const { ... } // virtual
};
class cAikaSek : public cAika {
int s;
public:
virtual void aseta(int ih=0, int im=0, int is=0) { // virtual
s = is; cAika::aseta(ih,im); lisaa(0); // järj. vaihd.
}
cAikaSek(int ih=0, int im=0, int is=0) { aseta(ih,im,is); }
virtual void lisaa(int lisa_min, int lisa_sek=0) { // virtual
s += lisa_sek; cAika::lisaa(lisa_min+s/60); s %= 60;
}
virtual void tulosta(int lf=1) const { // virtual
};
...
int main(void)
{
...
cAika *pAika;
pAika = &a1; pAika->tulosta();
pAika = &a4; pAika->tulosta();
return 0;
}Varoitus: Borlandin C++5.1:en optimoivalla kääntäjällä käännettynä em. koodi kaatoi kääntäjän ympäristöineen jos cAikaSek::aseta oli muodossa:
cAika::aseta(ih,im); s = is; lisaa(0);