Scrigroup - Documente si articole

Username / Parola inexistente      

Home Documente Upload Resurse Alte limbi doc  
AccessAdobe photoshopAlgoritmiAutocadBaze de dateCC sharp
CalculatoareCorel drawDot netExcelFox proFrontpageHardware
HtmlInternetJavaLinuxMatlabMs dosPascal
PhpPower pointRetele calculatoareSqlTutorialsWebdesignWindows
WordXml


Clase virtuale

c



+ Font mai mare | - Font mai mic



Clase virtuale


Din cauza mostenirii multiple se poate intampla ca o clasa de baza sa fie prezenta in mai multe exemplare intr-o clasa derivata. Sa consideram urmatorul exemplu:



Figura 1. Date membru mostenite in doua exemplare

In acest caz datele membru ale clasei animal vor fi mostenite in doua exemplare de catre clasa caine. Primul exemplar se mosteneste prin clasa domestic iar cel de al doilea prin clasa mamifer. Aceste date membru pot fi accesate folosind operatorul de rezolutie precedata de numele clasei prin care se face mostenirea. Fisierul animal1.cpp

#include <iostream.h>

#include <string.h>

#include <conio.h>

class animal ;

class mamifer : public animal ;

class domestic : public animal ;

class caine : public mamifer, public domestic ;

animal::animal(char* n)

mamifer::mamifer(char* n, int g): animal(n)

domestic::domestic(char* n, int c): animal(n)

caine::caine(char* n, int g, int c, int l): mamifer(n, g), domestic(n, c)

void caine::scrie_date()

int main()

Observam ca data membru nume s-a mostenit in doua exemplare de catre clasa caine, si referirea la aceste date s-a facut prin mamifer::nume respectiv domestic::nume. Prin executie se va afisa data membru nume de doua ori, mostenit prin cele doua clase. Deasemenea se va afisa greutatea si comportamentul cainelui, si faptul ca latra sau nu.

Ar fi de dorit insa ca numele sa fie memorat numai intr-un singur exemplar in obiectele clasei caine. Acest lucru se poate realiza cu ajutorul claselor virtuale.

Daca nu se doreste ca datele membru a unei clase de baza sa fie prezente in mai multe exemplare intr-o clasa derivata, atunci se folosesc clase virtuale. Clasele de baza devin virtuale prin mostenire, daca se specifica acest lucru prin plasarea cuvantului cheie virtual in fata numelui clasei, in lista claselor de baza. Astfel clasa de baza respectiva va deveni virtuala referitor la clasa derivata.

Exemplul de mai sus se modifica in modul urmator. Fisierul animal2.cpp

#include <iostream.h>

#include <string.h>

#include <conio.h>

class animal ;

class mamifer : virtual public animal ;

class domestic : virtual public animal ;

class caine : public mamifer, public domestic ;

animal::animal(char* n)

mamifer::mamifer(char* n, int g): animal(n)

domestic::domestic(char* n, int c): animal(n)

caine::caine(char* n, int g, int c, int l):

animal(n), //trebuie apelat constructorul clasei animal

mamifer(n, g),//in mod explicit, deoarece ea fiind virtuala

domestic(n, c)//constructorul nu se va apela prin unul din

//clasele mamifer sau domestic

void caine::scrie_date()

int main()


Intr-o ierarhie complicata de clase unele clase de baza pot fi mostenite in mai multe exemplare intr-o clasa derivata. Intre aceste exemplare pot fi virtuale si nevirtuale. Sa consideram urmatorul exemplu referitor la acest lucru :

Figura 2. Ierarhie de clase



In aceasta ierarhie de obiecte clasa de baza A se mosteneste in mod virtual de catre clasele B si C si in mod nevirtual de catre clasa D. Clasele de baza ale clasei G sunt B, C, D, E si F, toate mostenirile fiind nevirtuale cu exceptia clasei F. Se pot pune atunci urmatoarele probleme. In ce ordine vor fi executate constructorii in cazul in care se creaza un obiect al clasei G? Daca o clasa de baza este mostenita in mai multe exemplare intr-o clasa derivata printre care pot fi atat virtuale cat si nevirtuale, atunci de cate ori se va apela    constructorul clasei de baza? Pentru a da raspuns la aceste intrebari sa consideram urmatorul program. Fisierul virtual2.cpp

#include <iostream.h>

#include <string.h>

#include <conio.h>

class A

};

class B: virtual public A

};

class C: virtual public A

};

class D: public A

};

class E

};

class F

};

class G: public B, public C, public D, public E, virtual public F

};

int main()

Prin executie se obtine urmatorul rezultat:

Se apeleaza constructorul clasei A cu parametrul obiect

Se apeleaza constructorul clasei F cu parametrul obiect

Se apeleaza constructorul clasei B cu parametrul obiect

Se apeleaza constructorul clasei C cu parametrul obiect

Se apeleaza constructorul clasei A cu parametrul obiect

Se apeleaza constructorul clasei D cu parametrul obiect

Se apeleaza constructorul clasei E cu parametrul obiect

Se apeleaza constructorul clasei G cu parametrul obiect

Acest rezultat se datoreaza urmatoarelor reguli.

In cazul in care se creaza un obiect al clasei derivate, mai intai vor fi executate constructorii claselor de baza virtuale in ordinea din lista_claselor_de_baza (vezi declaratia claselor derivate), apoi constructorii claselor de baza nevirtuale in ordinea din lista_claselor_de_baza

Daca intr-o ierarhie de clase, o clasa de baza se mosteneste in mai multe exemplare intr-o clasa derivata, atunci la crearea unui obiect al clasei derivate se va executa constructorul clasei de baza o data pentru toate exemplarele virtuale, si inca de atatea ori cate exemplare nevirtuale exista.

Deci in cazul exemplului de mai sus, mai intai se execut constructorii claselor A si F (ele fiind virtuale), apoi constructorii claselor B, C, D si E (clase nevirtuale). Constructorul clasei D apeleaza mai intai constructorul clasei A (ea fiind nevirtuala de aceasta data). De aceea ordinea de apelare a constructorilor va fi: A, F, B, C, A, D, E si G.





Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 835
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved