Posljednja izmjena: 06.03.2002
Sintaksa nasljeđivanja
Nasljeđivanjem se omogućuje korištenje nekih članova i metoda osnovnog razreda
od strane izvedenog razreda. Nasljeđivanje se u C++ realizira navođenjem
imena osnovnog razreda iza imena izvedenog razreda kako slijedi:
class OsnovniRazred
{ ... }
class IzvedeniRazred : public
OsnovniRazred
{ ... }
Kao modifikator pristupa mogu se navesti ključne riječi public,
private ili protected, koje tada mijenjaju pristup članovima
objekta izvedenog razreda iz drugih dijelova programa. Tablica izvođenja
je sljedeća:
izvođenje sa | pristup u osnovnom r. | pristup u izvedenom r. |
public | public | public |
protected | protected | |
private | private | |
protected | public | protected |
protected | protected | |
private | private | |
private | public | private |
protected | private | |
private | private |
Npr. ako je neki član u osnovnom razredu bio public, dakle moglo
mu se pristupiti iz bilo kojeg dijela programa, a modifikator izvođenja
je protected, tada se tom članu neće moći pristupiti preko objekta
izvedenog razreda jer je tamo postao protected, dok mu se način
pristupa u osnovnom razredu ne mijenja.
Unutar metoda izvedenog razreda može se pristupati svim public ili
protected članovima osnovnog razreda, dok se private članovima
ne može pristupiti.
Jednostruko ili jednostavno nasljeđivanje je takvo nasljeđivanje
kod koga izvedeni razred ima samo jedan osnovni razred. U sljedećem primjeru
razred koji predstavlja realni broj korišten je kao osnova razredu koji će
dodati operator zbrajanja; drugim riječima, razred RBr_Zbrajanje
je naslijedio razred RBr:
class RBr
{ protected:
double r;
public:
void Set(double _r)
{ r=_r; }
double Get(void)
{ return r; }
};
class RBr_Zbrajanje: public RBr
{ public:
RBr_Zbrajanje operator+ (const RBr_Zbrajanje& op2)
{ RBr_Zbrajanje rezultat;
rezultat.r=(*this).r+op2.r;
return rezultat;
}
};
...
RBr_Zbrajanje a,b,c;
a.Set(1); // koristimo metodu osnovnog
razreda
b.Set(2);
c=a+b;
c.Get();
Razred izveden iz nekoga drugoga osnovnog razreda nasljeđuje sve njegove članove
i metode, tako da se metode mogu pozivati i preko objekata izvedenog razreda. Konstruktori i destruktori se ne nasljeđuju. Pri inicijalizaciji objekta
izvedenog razreda implicitno se pozivaju i konstruktor izvedenog i osnovnog
razreda.
Polimorfizam i virtualne funkcije
Nasljeđivanjem razreda možemo konstruirati hijerarhijsku strukturu
koja će nam poslužiti za lakše oblikovanje programskog koda. Zajednička
svojstva grupe razreda mogu biti sadržana u jednom ili više nadrazreda
iz koga su ostali izvedeni. Imamo li više izvedenih razreda, možemo pojednostaviti
rukovanje s njima koristeći pokazivač ili referencu na osnovni razred.
Pokazivač tipa osnovnog razreda može, osim na objekte osnovnog razreda,
pokazivati i na bilo koji objekt izvedenih razreda, kojima nije jednak
po tipu. Ovisno o vrsti objekta na koji pokazuje, prevodilac može različito
interpretirati upotrebu takvog pokazivača (polimorfizam).
OsnovniR *p;
IzvedeniR1 a;
IzvedeniR2 b;
p=&a;
p=&b;
p=new IzvedeniR3;
Izvedeni razred moći će koristiti public i protected metode osnovnog razreda, ali se te metode također mogu i nadopuniti ili čak nanovo definirati u izvedenom razredu. Ispred deklaracije metode osnovnog razreda koja će biti redefinirana u nekom izvedenom razredu potrebno je staviti ključnu riječ virtual. Tada će prevodilac pozvati istoimenu metodu izvedenog razreda, čak i kada je pokazivač, koji pokazuje na objekt izvedenog razreda, po tipu osnovnog razreda.
class Osnovni
{ public:
virtual void virt_fun(void)
{ ... }
void fun(void)
{ ... }
};
class Izvedeni
{ public:
void virt_fun(void)
{ ... }
void fun(void)
{ ... }
};
...
Osnovni *p = new Izvedeni;
p->fun();
// izvrsit ce se funkcija Osnovni::fun()
p->virt_fun(); // izvrsit ce se funkcija
Izvedeni::virt_fun()
...
p->Osnovni::virt_fun()
// ako bas zelimo pozvati funkciju
iz osnovnog razreda, mozemo joj
// pristupiti operatorom dosega ::
U tijelu redefinirane metode u izvedenom razredu možemo također pozvati i istoimenu metodu osnovnog razreda (npr. ako je dio posla koji obavljamo identičan) sa:
void Izvedeni::virt_fun()
{ ...
Osnovni::virt_fun();
...
}