Ebben az alfejezetben az öröklés fogalmánál használt grafikus példát folytatjuk.
Az elõzõekben láthattuk, hogy egy osztálynak nemcsak adatmezõi, hanem függvénymezõi (function members) is lehetnek. Egy függvénymezõ nem más, mint egy, a class definíción belül deklarált függvény. (A függvénymezõket más OOP nyelvekben, például a Smalltalk-ban, vagy a Turbo Pascal-ban metódusoknak hívják).
Most deklaráljunk egy get_x azonosítójú függvénymezõt a point osztály számára. Ezt kétféleképpen tehetjük meg:
class point
{ int x;
int y;
colortype color;
int get_x(void) { return x; };
....
// implicit inline definicio
};
Ez a fajta definíció alapértelmezésben inline
függvényként definiálja a get_x-et.
Ez az ún. implicit inline függvény definició.
Figyeljük meg, hogy az implicit inline függvénydefiníció
szintaxisa a hagyományos C-ben megszokottak szerinti.
A második lehetõségnél a C-szintaxissal csak deklaráljuk a get_x függvényt a point osztályban, és késõbb adjuk meg a függvény teljes definicióját:
class point
{ int x;
int y;
colortype color;
int get_x(void);
// majd definialjuk
....
};
int point::get_x(void)
{
return x;
}
// Itt jobb lenne az implicit inline definicio
Figyeljük meg alaposan, hogy használtuk a :: hatáskört
definiáló operátort (scope resolution operator)
a point::get_x függvénydefinícióban.
A point osztályazonosító szükséges
ahhoz, hogy a fordítóprogram tudja, melyik osztályhoz
is tartozik a get_x függvénydefiníciója,
valamint tudja azt is, hogy mi az érvényességi tartománya.
Ez tehát azt jelenti, hogy a pont::get_x függvény
(a hagyományos globális változókon kívül)
csak a point osztályhoz tartozó objektumok mezõihez
férhet hozzá. Természetesen létezhet több,
más osztályhoz tartozó get_x függvény
is. (Erre a lehetõségre - bár nem explicit módon
- utaltunk a többrétûség tárgyalásánál.)
Az osztály-deklaráción belüli függvény-definició
esetében természetesen nem volt szükség az érvényességi
tartományt definiáló point:: elõtagra,
hiszen a get_x függvény hovatartozása abban
az esetben teljesen egyértelmû volt.
A hovatartozás definiálásán túlmenõen a point::-nak más szerepe is van. Hatása kiterjed az õt követõ függvénydefinícióra oly módon, hogy a get_x függvényen belül az x azonosítójú változóra való hivatkozás a point struktúra x azonosítójú adatmezõjére vonatkozik, valamint a get_x függvény a point osztály hatáskörébe kerül (lásd a 2.6.2-es részt).
Függetlenül attól, hogy a függvénymezõt milyen módon definiáljuk, a lényeg az, hogy van egy get_x nevû függvényünk, ami szorosan hozzá van kapcsolva a point névvel ellátott osztályhoz. Mivel a get_x-et mezõként definiáltuk a point számára, a point minden adatmezõjéhez hozzáférhet. Ebben az egyszerû példánkban get_x egyszerûen csak x értékét szolgáltatja.
Elképzelhetõ, hogy egy származtatott típusban lokálisan deklarálunk egy függvénymezõt, melynek azonosítója és paraméterlistája is megegyezik egy õstípusban definiált függvénymezõ azonosítójával és paraméterlistájával, ugyanakkor a definíció során fel szeretnénk használni az õstípusbeli változatot. Mivel a késõbbi definícióban lévõ függvénymezõ a saját hatáskörében elfedi a korábbi definíciót, a származtatott típusban csak az érvényességi tartományt defináló operátor segítségével használhatjuk az õstípusban definiált, "elfedett" függvénymezõt. Erre vonatkozóan (az eddigi példánkat egy kicsit félretéve) tekintsük az alábbi deklarációkat:
class rectangle { int a, b; // Negyszog adatai
...
void show(void); // Kirajzolja
};
class triangle { int a, b, c;// Haromszog adatai
...
void show(void); // Kirajzolja
};
class house : rectangle, // Ostipusok
triangle
{ // Egy hazat definial
...... // Tetszoleges mezok
void show(void); // Kirajzolja
};
// Az egyes fuggvenymezok definicioi:
void rectangle::show( ) { ... } // Egy negyszoget rajzol
void triangle::show( ) { ... } // Egy haromszoget rajzol
void house::show( ) // Egy hazat rajzol
{
// Itt az egyszeru 'show' azonosito a 'house' tipus
// fuggvenymezojet jelenti, a 'show' hivas rekurzio lenne
rectangle::show( ); // alap
...
triangle::show( ); // teto
...
::show( ); // Egy globalis, 'show' fuggveny hivasa
};
Amint az fenti példából is látszik, ha egy
hagyományos, nem egy osztály függvénymezõjeként
deklarált show függvényt akarunk meghívni,
akkor a függvénynév elé egy "üres" érvényességi
tartományt definiáló operátort (::)
kell tennünk (azaz nem utaljuk egy osztály hatáskörébe
sem, így a teljes programra nézve globális lesz a
függvény). Ezután a kitérõ után
a foglalkozzunk tovább a megszokott point / location
példával.