Funcții virtuale

Partea 2. Clasele abstracte și un exemplu de utilizare

Să continuăm să luăm în considerare utilizarea funcțiilor virtuale, începute în prima parte a articolului. De data aceasta vă ofer un exemplu concret. Lăsați-o să fie foarte simplă, dar este pe deplin funcțională și vă permite să demonstrați toate subtilitățile despre care ați citit deja.
Dar, pentru început, există încă un pic de teorie care nu a fost inclusă în prima parte.

Funcții virtuale nete

S-ar putea să vă gândiți că toate celelalte funcții sunt murdare! Nu, desigur. Curatarea in acest caz inseamna literalmente o functie goala. Să vedem ce este o funcție virtuală pură.

După cum puteți vedea, singura diferență este că există un design = 0, care se numește un specificator pur. O funcție virtuală pură nu face absolut nimic și nu este disponibilă pentru apeluri. Scopul său este să servească ca bază (dacă doriți, un șablon) pentru funcțiile de înlocuire din clasele derivate. O clasă care conține cel puțin o funcție virtuală pură se numește o clasă abstractă. De ce abstracte? Pentru că este imposibil să creați obiecte independente din această clasă. Aceasta este doar o pregătire pentru alte clase. Mecanismul clasei abstracte este conceput pentru a reprezenta concepte generale, care pe viitor ar trebui să fie concretizate. Aceste concepte generale nu pot fi folosite direct, dar pe baza lor este posibil ca pe baza construirii unor clase private derivate adecvate pentru descrierea obiectelor specifice.
Un exemplu? Vă rog.

Toate animalele din comportamentul lor au funcții precum mâncarea, băutul, dormitul, producția de sunet. Este logic să definim o clasă de bază în care să declarăm imediat toate aceste funcții și să le facem pur virtuale. Și apoi din această clasă derivă clase care descriu anumite animale (sau specii), cu comportamentul lor specific. Și clasa de bază este de fapt abstractă. La urma urmei, nu descrie nici un animal mai mult sau mai puțin specific (chiar și speciile de animale). Poate fi atât pește, cât și păsări de curte sunt lucruri diferite!
Ca orice clasă, o clasă abstractă poate avea un constructor explicit definit. Puteți apela metodele clasei de la constructor. Dar chemarea constructorului la funcții virtuale pure va duce la erori în timpul executării programului.
În comparație cu clasele obișnuite, clasele abstracte au drepturi limitate. După cum am menționat deja, este imposibil să creați un obiect al unei clase abstracte. O clasă abstractă nu poate fi utilizată pentru a specifica tipul unui parametru al funcției sau ca tip al valorii returnate. Nu poate fi folosit cu casturi explicite. Dar puteți defini referințele și indicii la clasele abstracte.
Toate acestea, bine, sau aproape totul, acum ne uităm la un exemplu.

Cel mai simplu program

Revenind la exemplul militant din prima parte, trebuie să spun că în acest caz este absolut iubitor de pace și chiar un exemplu pentru copii. Apropo, în ciuda simplității sale, ar putea fi baza pentru crearea celui mai simplu joc de dezvoltare pentru copiii foarte mici.
Ei bine, atunci. Ideea se bazează pe ideea de cunoaștere a lumii animalelor. (Cool a declarat) Nu este un secret (sper) că toate animalele fac sunete. Și diferită și foarte caracteristică pentru acest gen. Pe asta și joacă.
Pentru a simplifica exemplul, ne limităm la descrierea fiecărui animal prin porecla și sunetul tipic produs de animal. Ei bine, principala (și, din păcate, singura) posibilitate a programului va fi rezultatul unei liste de porecle de animale și prezentarea sunetelor pe care le fac.

Ca clasă de bază, am construit o clasă abstractă Animal. El are un singur membru de titlu de date care descrie numele animalului. Are un constructor explicit definit care atribuie animalului numele animalului. Și singura funcție virtuală pură (), care descrie ceea ce sună animalul emit.
Din această clasă sunt listate toate celelalte. În afară de unul. Leul de clasă se naște din clasa de pisici (la urma urmei, leii sunt și pisici!). Acest lucru este făcut pentru a demonstra complexitatea utilizării funcțiilor virtuale. Dar despre această clasă un pic mai târziu. Și acum cum funcționează programul.
Toate clasele derivate descriu funcția lor virtuală de înlocuire (), care imprimă pe ecran ce fel de sunete emite un anumit animal.
În corpul principal al programului, este declarată o serie de animale [4] de indicatori de tipul Animal *. Și a creat imediat obiecte de clasă dinamice și a umplut o serie de indicii. Și în for () loop, funcția virtuală speak () este pur și simplu apelată de pointer.
Dacă nu ați făcut noi greșeli la intrarea în program, ieșirea ar trebui să arate astfel:

Și sistemul de ajutor de la Borland C ++ 5 va oferi următorul ajutor:

Acesta este cazul când o funcție virtuală de înlocuire este declarată cu același tip de valoare de retur, dar cu un set diferit de parametri. Ceea ce în cazul sunetului pe care îl emite leul poate fi transmis funcției speak () ca parametru? Asumarea tipului de loc în care se emite sunetul este rupt imediat și irevocabil. Să presupunem că aceasta este o dependență de timp, adică când. Ei bine, de exemplu, mai aproape de noapte, leul a vrut să doarmă și a început să se căsătorească. Prin urmare, în acest caz, funcția Când (int Când) este trecută la parametrul Când, care nu este utilizat nicăieri în funcție, dar nu contează. Funcția va funcționa oricum.
Ei bine, odată ce programul este compilat, trebuie să-l rulați. Ce sa întâmplat? Ar trebui să existe următoarele:

Wow! Ceva pare să fie greșit! Leul nu mârâie la tine și nu căscă, dar miaje drăguțe. De ce ar fi? Dar compilatorul a avertizat funcția 'Lion :: vorbi (int)' ascunde (suprascrie) funcția virtuală 'Cat :: vorbi ()'. Aceasta este o funcție complet diferită! Prin urmare, odată ce nu există o funcție virtuală bine definită în această clasă, funcția virtuală vorbește () din clasa de bază este apelată de pointer. Și în cazul nostru, clasa de bază pentru clasa Leu este clasa Cat. Iată un leu la tine și zamyukal!

Aici, până acum, asta e tot. Am terminat analiza teoriei funcțiilor virtuale în cazul general. Cu toate acestea, nu am luat în considerare multe puncte diferite. Dar acestea sunt deja subtilități foarte subtile. Puteți scrie o carte despre acest lucru.
În partea următoare, vom încerca să luăm în considerare un moment ușor mai complicat. Să vedem ce sunt distrugătoarele claselor virtuale, de ce sunt necesare și cum să le rezolvăm.

Articole similare