Virtuális függvények és absztrakt osztályok
Előadás 18. Többszörös öröklés
Egy osztály lehet létrehozni bármely számú bázis osztályok. Miután több mint egy közvetlen szülő osztály úgynevezett többszörös öröklés.
osztály;
B osztály;
C osztály;
osztályú D. nyilvánosságra, nyilvános B, magán C;
Egy mutatót az származtatott osztály átadhatók egy függvény, amely elvárja egy mutatót az egyik a bázis osztályok. E mechanizmus magában foglalja az egyszerű összeállítása technikák, hogy egy függvény, amely elvárja a mutató egy alap osztály, lásd a részét a származtatott osztály, amely eltér attól, amelyik megjelenik a funkció, amely elvárja a mutatót egy másik alap osztály. Virtuális függvények a szokásos módon működnek.
osztály
Az osztály nem lehet meghatározni, mint egy azonnali alap osztály többször, de lehet, hogy többször közvetett alap osztály.
osztály <.>; B osztály: nyilvános A, nyilvánosságra;
osztály <.>; B osztály: nyilvános A; C osztály: nyilvános A; D osztályú: nyilvános B, nyilvános C;
Itt egy D osztályú létesítmény lesz két al-objektum osztály A.
A származtatott osztály és annak alap osztályok leírható mint egy irányított aciklikus gráf.
Mivel objektum D két működtetés objektum A. (explicit vagy implicit) között az A és egy mutató a mutató egy D egyértelmű, és ezért tilos.
D * PD = új D; A * pa = pd; PA = (A *) PD; pa = (B *) pd; pa = (C *) pd;
// Ambiguity! // Minden ugyanaz a kétértelműség! // csökkentését egy mutató a B tárgy // csökkentését egy mutatót az objektum C.
Azonban az osztály lehet közvetlen és közvetett alap osztály.
osztály <.>; B osztály: nyilvános A <.>; C osztály: nyilvános A <.>; D osztályú: nyilvános A, nyilvános B, nyilvános C <.>; pa = pd; pa = (B *) pd; pa = (C *) pd;
// Can! // Hoz egy mutatót az objektum el azonnal D // csökkentését egy mutató a B tárgy // csökkentését egy mutatót az objektum C.
// A :: f (int) megnyíltak
// A funkciót A :: f (int) // Hívás funkció B1 :: f (dupla) // hívás funkciót B2 :: f (char) // hívás funkciót C :: f (char *)
Az alap osztály leíró, felveheti a kulcsszó virtuális.
osztály <.>; B osztály: a virtuális nyilvánosság <.>; C osztály: a virtuális nyilvánosság <.>; D osztályú: nyilvános B, nyilvános C <.>;
Ebben az esetben a D osztályú csak egy példánya a A. Grafikailag ez így néz ki:
Egy osztály egyaránt tartalmazhat virtuális és nem virtuális alap osztály az ilyen típusú.
osztály <.>; B osztály: a virtuális nyilvánosság <.>; C osztály: a virtuális nyilvánosság <.>; D osztály: nyilvános A <.>; E osztályú: nyilvános B, nyilvános C, nyilvános D <.>;
Itt E osztály magában foglalja a két osztály egyedeire A. D. egyik osztály és egy másik csoportját a virtuális megosztott osztályok A. B. és C.
osztály <.>; B osztály: a virtuális nyilvánosság <.>; C osztály: a virtuális nyilvánosság <.>; D osztályú: nyilvános A, nyilvános B, nyilvános C <.>;
// Nem lehet! Hozza az osztály nem egyértelmű.
Annak megállapítására funkciók osztály egy virtuális alap osztály programozó, általában nem lehet tudni, hogy az alap osztály együtt használják más osztályokba. Lehet valami probléma van a végrehajtását az algoritmusok, amelyek előírják, hogy az alap osztály funkciót nevezik pontosan egyszer. Nyelv biztosítja, hogy a virtuális alap osztály konstruktora nevezzük csak egyszer. Constructor úgynevezett virtuális alap osztály (közvetlenül vagy közvetve) az objektum kivitelező (a kivitelező a „rövid szénláncú” származtatott osztály).
osztály
Ha szükséges, a programozó képes szimulálni ez az áramkör, ami az alap osztály virtuális függvény csak a „rövid szénláncú” származtatott osztály.
A származtatott osztály felülírhatja a virtuális függvény a közvetlen vagy közvetett virtuális alap osztály. Két különböző osztályok felülírhatja virtuális függvények különböző virtuális alap osztály. Ily módon több származtatott osztályokban is hozzájárulhat, hogy a végrehajtás a bemutatott felület egy virtuális alap osztály. A () <> virtuális void g (); virtuális void h ();>; B1: virtuális nyilvánosság // Hívás funkció B1 :: g // hívás funkciót B2 :: h Ha két osztály helyére az azonos alap osztály funkciót, így azok származtatott osztály, nem helyettesíti ez a funkció érvénytelen. Ebben az esetben nem lehet létrehozni asztal virtuális függvények, mert ez a függvény nem egyértelmű. // függvény C :: g felülbírálja funkció B1 :: g, és B2 :: g // Rendben - A funkciót C :: g // kétértelműséget - B1 :: H vagy B2 :: h. Sok osztályok egyszerű és közös kapcsolódási pontok által használt számos különböző módon. A pontos érték minden interfész célfüggvény kerül meghatározásra, amelyre ez az úgynevezett. Gyakran a program egy kérelmet és a téma őket befogadó egy szoftver réteg. Ideális esetben a köztes kódot nem kell tudni semmit az egyes tranzakciók, különben el kellett volna módosítani kell minden egyes alkalommal, amikor változik olyan műveletek. Következésképpen egy ilyen köztes kódot kell egyszerűen továbbítja a kérelmet a kedvezményezett az adatok egy részét képviselő művelet lehet hivatkozni. Egy egyszerű módja annak, hogy végre ez a megközelítés, hogy küldje el a húr képviselete a művelet, amelynek meg kell nevezni. Azonban ez a vonal valakinek, hogy hozzon létre, és valaki - dekódolni, hogy meghatározza, hogy milyen műveleteket megfelelnek. Ez elég nehéz és kényelmetlen. Lehetséges lenne, hogy küldjön egészek megfelelő műveleteket. Ugyanakkor, bár a szám és kényelmes számítógép, az emberek értékük nem egyértelmű. És még mindig szükség van egy kód, hogy meghatározzák, hogy mit kíván hívni. C ++ eszközt biztosít közvetett hivatkozások a tanulót. A mutató egy osztály tagja egy olyan érték, amely azonosítja egy osztály tagja. Akkor kezelni, mint egy osztály tagja helyzetben az osztály az objektum, de természetesen a fordító figyelembe veszi a különbségek az adatokat virtuális függvények nonvirtual funkciók stb Egy mutatót az M osztályú tagot alkalmazunk kombinációban a tárgy. Az üzemeltetők -> * és. * Hagyjuk a programozó, hogy kifejezze a következő sorrendben. p-> * m m csatlakozik az objektum által mutatott p. és obj. M * m kötődik az objektum obj. Az eredmény összhangban használják típusú m. Nem lehet menteni az ilyen műveletek eredményeként annak későbbi használatra. Természetesen, ha tudtuk, hogy mi az a tagja, az osztály a használni kívánt tudtuk ezt nélkül közvetlenül mutatók. Valamint rámutatnak a szokásos funkciók, mutatókat az osztály tagjai használják, amikor szükség van, hogy olvassa el egy tárgy, amelynek neve ismeretlen. Azonban, ellentétben a mutató egy változó vagy egy szabályos működését a tanulót mutató csak egy mutatót a memória területet. Ez megfelel több, eltolódás a szerkezet egy index a tömbben. A kombináció a mutató egy tagja, az osztály egy tárgy vagy egy mutatót egy objektum ad neki, amely azonosítja egy adott tagja egy adott objektumot. Base () <>>; osztály D1: nyilvános adatbázisa typedef void (Base :: * PF) (); void main () // Határozza meg a mutató, amely egy tag függvény osztály Base // tárolja egy mutató a tanulót // Base (nyit és zár funkció virtuális, // és a nyomtatási funkció - nem virtuális). // d - D1 osztály objektum // hívás D1 funkció :: open () // A funkciót D1 :: close () // függvény hívás Base :: print () // pb - mutató egy objektum osztály Base (tárgy valójában tartozik osztály D2) // a funkciót D2 :: open () // a funkciót D2 :: close () // függvényhívás Base :: print () Alakzatok () #include "Shapes.h" int alakzatok :: count = 0; #define tárolható #include Tárolható (); virtuális int Read () = 0; virtuális int Write () = 0;>; #include "Storable.h" Tárolható :: tárolható (const char * f1, const char * f2) #if. meghatározott (alakzatok) #include "Shapes.h" #endif class Circle: nyilvános alakzatok Kör () <> void Draw (); void Mozgatás (int, ahol, const alakzatok * alakja);>; #if. meghatározott (alakzatok) #include "Shapes.h" #endif osztály Triangle: nyilvános alakzatok Triangle () <> void Draw (); void Mozgatás (int, ahol, const alakzatok * alakja);>; #include "Circle.h" #ha. meghatározott (tárolható) #include "Storable.h" #endif osztály Circle_Storable: nyilvános Circle, virtuális nyilvános tárolható Circle_Storable () <> int read (); int Write ();>; #include "Triangle.h" #ha. meghatározott (tárolható) #include "Storable.h" #endif osztály Triangle_Storable: nyilvános Triangle, virtuális nyilvános tárolható Triangle_Storable () <> int read (); int Write ();>; #include "Circle_Storable.h" #include "Triangle_Storable.h" void main ()
osztály
osztály
osztály Base Shapes.h fájl
Shapes.cpp fájl
Storable.h fájl
Storable.cpp fájl
Circle.h fájl *
Triangle.h fájl *
Circle_Storable.h fájl
Circle_Storable.cpp fájl
Triangle_Storable.h fájl
Triangle_Storable.cpp fájl
main.cpp fájl