ex ~thereau~ ,new nick Rapk1d
Salut [b]Vizitator ! Ai postat pana acum 5mesaje.
Esti inscris din data de
Joi Ian 01, 1970.[color=green]
Ultima vizita a fost in Joi Ian 01, 1970.
Sa ii uram bun venit lui ionutpogonici , ultimul membru! Inregistreaza-te si intra in staff-ul nostru![/b]

Alăturați-vă forumului, este rapid și ușor

ex ~thereau~ ,new nick Rapk1d
Salut [b]Vizitator ! Ai postat pana acum 5mesaje.
Esti inscris din data de
Joi Ian 01, 1970.[color=green]
Ultima vizita a fost in Joi Ian 01, 1970.
Sa ii uram bun venit lui ionutpogonici , ultimul membru! Inregistreaza-te si intra in staff-ul nostru![/b]
ex ~thereau~ ,new nick Rapk1d
Doriți să reacționați la acest mesaj? Creați un cont în câteva clickuri sau conectați-vă pentru a continua.

Clase [c++]

In jos

 Clase [c++] Empty Clase [c++]

Mesaj Scris de ~thereau~ Mar Aug 10, 2010 2:37 pm

]3.1. Declararea claselor[/b]


O sintaxa simplificata a declararii unei clase este urmatoarea:

class NumeClasa
{
...
declaratii variabile membre
...
declaratii functii membre
...
}



Dupa cum se poate observa din aceasta alcatuire a declaratiei, clasa
este asemanatoare cu o structura din limbajul C, dar care poate avea in
componenta sa membri atat de tip variabila cat si de tip functie. Asa cum
spuneam si in capitolul precedent, pentru datele din interiorul clasei se
utilizeaza de obicei termenul de date membre, iar pentru functii
denumirea de functii membre sau metode. O clasa permite
incapsularea in interiorul sau a datelor si a codului.
Intocmai ca in limbajul C, pentru a putea utiliza efectiv un tip de
date (in cazul de fata o clasa), trebuie sa definim o variabila de acel tip.
Intr-un mod similar declaratiei

int i;

putem scrie:

NumeClasa variabila

Vom considera de acum incolo ca variabila poarta numele de
obiect. Exprimarea uzuala este ca un obiect este instantierea unei
clase
.


3.2. Membrii unei clase


Accesarea membrilor unei clase se face ca in cazul structurilor din
limbajul C:

obiect.VariabilaMembra = valoare

pentru accesul la o variabila membra, si

obiect.FunctieMembra()

pentru apelarea unei functii membre.
Pentru exemplificare sa consideram o implementare a notiunii de
punct. Ca variabile membre avem nevoie doar de coordonatele x si y care
definesc pozitia in spatiu a unui punct. Am mai declarat o functie care
calculeaza aria dreptunghiului avand colturile (0, 0) si (x, y).

class Point
{
unsigned x, y;
unsigned long Arie()
{
return x * y;
};
unsigned GetX();
unsigned GetY();
void SetX(unsigned X);
void SetY(unsigned Y);
};


unsigned Point::GetX()
{
return x;
}


unsigned Point::GetY()
{
return y;
}


void Point::SetX(unsigned X)
{
x = X;
}


void Point::SetY(unsigned Y)
{
y = Y;
}



Am folosit un operator nou, specific C++, ::, numit operator de
rezolutie
, numit si operator de acces sau de domeniu. El
permite accesul la un identificator, dintr-un bloc in care acesta nu este
vizibil datorita unei alte declaratii locale. Un exemplu de folosire este
urmatorul:


char *sir = "variabila globala";

void functie()
{
char *sir = "variabila locala";
printf("%s\n", ::sir); // afiseaza variabila globala
printf("%s\n", sir); // afiseaza variabila locala
}

Pentru definitiile functiilor membre aflate in afara declaratiei clasei
este necesara specificarea numelui clasei urmat de acest operator, indicand
faptul ca functia are acelasi domeniu cu declaratia clasei respective si este
membra a ei, desi este definita in afara declaratiei.


3.3. Crearea si distrugerea obiectelor


Sa consideram urmatorul program C++:

void main()
{
Point p;
}


In momentul definirii variabilei p, va fi alocat automat
spatiul de memorie necesar, acesta fiind eliberat la terminarea programului.
In exemplul de mai sus, variabila p este de tip static. In continuare
vom modifica acest program pentru a folosi o variabila dinamica (pointer).

void main()
{
Point *p;


p = new Point;
p->x = 5;
p->y = 10;
printf("Aria = %d\n", p->Aria());
delete p;
}


Ati observat utilizarea unor operatori pe care nu ii cunoasteti din
limbajul C: new si delete. C++ introduce o metoda noua pentru
gestiunea dinamica a memoriei, similara celei utilizate in C (malloc() si
free()), dar superioara si special construita pentru programarea orientata
pe obiecte. Operatorul new este folosit pentru alocarea memoriei, iar
sintaxa acestuia este:

variabila = new tip;
variabila = new tip(valoare_initiala);
variabila = new tip[n];

Este usor de intuit ca prima varianta aloca spatiu pentru
variabila dar nu o initializeaza, a doua varianta ii aloca spatiu si o
initializeaza cu valoarea specificata, iar a treia aloca un tablou de dimensiune
n. Acest operator furnizeaza ca rezultat un pointer continand adresa
zonei de memorie alocate, in caz de succes, sau un pointer cu valoarea NULL
(practic 0) atunci cand alocarea nu a reusit.
Eliminarea unei variabile dinamice si eliberarea zonei de memorie
aferente se realizeaza cu ajutorul operatorului delete. Sintaxa
acestuia este:

delete variabila;

Desi acesti doi operatori ofera metode flexibile de gestionare a
obiectelor, exista situatii in care aceasta nu rezolva toate problemele (de
exemplu obiectele care necesita alocarea unor variabile dinamice in momentul
crearii lor). De aceea pentru crearea si distrugerea obiectelor in C++ se
folosesc niste functii membre speciale, numite constructori si
destructori.
Constructorul este apelat automat la instantierea unei
clase, fie ea statica sau dinamica.
Destructorul este apelat automat la eliminarea unui obiect, la
incheierea timpului de viata in cazul static, sau la apelul unui
delete in cazul dinamic.
Din punct de vedere cronologic, constructorul este apelat dupa
alocarea memoriei necesare, deci in faza finala a crearii obiectului, iar
destructorul inaintea eliberarii memoriei aferente, deci in faza initiala a
distrugerii sale.
Constructorii si destructorii se declara si se definesc similar cu
celelalte functii membre, dar prezinta o serie de caracteristici specifice:
  • numele lor coincide cu numele clasei careia ii apartin; destructorii
    se disting de constructori prin faptul ca numele lor este precedat de
    caracterul ~
  • nu pot returna nici un rezultat
  • nu se pot utiliza pointeri catre constructori sau destructori
  • constructorii pot avea parametri, destructorii insa nu. Un
    constructor fara parametri poarta denumirea de constructor implicit.
  • De remarcat este faptul ca in cazul in care o clasa nu dispune de
    constructori sau destructori, compilatorul de C++ genereaza automat un
    constructor respectiv destructor implicit.
    Sa completam in continuare clasa Point cu un constructor si un
    destructor:

    Point::Point()
    // constructor implicit
    {
    x = 0;
    y = 0;
    }


    Point::Point(unsigned X, unsigned Y)
    {
    x = X;
    y = Y;
    }


    Point::~Point()
    {
    }



    Ati remarcat cu aceasta ocazie modul de marcare a comentariilor in
    C++: tot ce se afla dupa caracterul // este considerat
    comentariu.
    De notat este faptul ca definitii de forma
    Point p;

    sau

    Point *p = new Point();

    duc la apelarea constructorului implicit.
    O intrebare care poate apare este motivul pentru care am realizat
    functiile GetX(), GetY(), SetX(), SetY(), cand puteam utiliza direct
    variabilele membru x si y. Deoarece una din regulile
    programarii C++, adoptata in general de catre specialisti, este de a proteja
    variabilele membru (veti afla in capitolul urmator cum), acestea neputand fi
    accesate decat prin intermediul unor functii, care au rolul de metode de
    prelucrare a datelor incapsulate in interiorul clasei
    .


    3.4. Conceptul de mostenire


    Daca intrebam un zoolog ce este un caine, ne va raspunde ca este un
    reprezentant al speciei canine domesticus. Un caine este un tip de
    carnivor, un carnivor este un tip de mamifer, si asa mai departe. Zoologul
    imparte animalele in regn, clasa, ordin, familie, gen si specie. Aceasta
    ierarhie stabileste o relatie de genul "este un/este o". Putem remarca
    acest tip de relatie oriunde in aceasta lume: Mercedes este un tip de
    masina, care la randul sau este un tip de autovehicul, si exemplele pot
    continua. Astfel, cand spunem ca ceva este un tip de altceva diferit, spunem ca
    este o specializare a acelui lucru, asa cum o masina este un tip mai special de
    autovehicul.
    Conceptul de caine mosteneste, deci primeste in mod automat, toate
    caracteristicile unui mamifer. Deoarece este un mamifer, cunoastem faptul ca se
    misca si respira aer - toate mamiferele se misca si respira aer prin definitie.
    Conceptul de caine aduce in plus ideea de a latra, de a misca coada, si asa mai
    departe. Putem clasifica mai departe cainii in caini de paza si caine de
    vanatoare, iar cainii de vanatoare in cocker spanioli si dobermani, etc.
    Asa cum am vazut mai sus, conceptul de mostenire este o notiune foarte
    naturala si pe care o intalnim in viata de zi cu zi. In C++ intalnim notiunea
    de derivare, care este in fapt o abstractizare a notiunii de mostenire.
    O clasa care adauga proprietati noi la o clasa deja existenta vom spune ca
    este derivata din clasa originala. Clasa originala poarta denumirea de
    clasa de baza.
    Clasa derivata mosteneste toate datele si functiile membre ale clasei de
    baza; ea poate adauga noi date la cele existente si poate suprascrie sau adauga
    functii membre. Clasa de baza nu este afectata in nici un fel in urma acestui
    proces de derivare si ca urmare nu trebuie recompilata. Declaratia si codul
    obiect sunt suficiente pentru crearea clasei derivate, ceea ce permite
    reutilizarea si adaptarea usoara a codului deja existent, chiar daca fisierul
    sursa nu este disponibil. Astfel, nu este necesar ca programatorul unei clase
    derivate sa cunoasca modul de implementare a functiilor membre din componenta
    clasei de baza.
    O notiune noua legata de derivare este cea de supraincarcare sau
    suprascriere a functiilor membre. Aceasta se refera, in mod evident, la
    redefinirea unor functii a clasei de baza in clasa derivata. De notat este
    faptul ca functiile originale din clasa parinte sunt in continuare accesibile
    in clasa derivata, deci caracteristicile clasei de baza nu sunt pierdute.
    Dintr-o clasa de baza pot fi derivate mai multe clase si fiecare clasa
    derivata poate servi mai departe ca baza pentru alte clase derivate. Se poate
    astfel realiza o ierarhie de clase, care sa modeleze adecvat sisteme
    complexe. Pornind de la clase simple si generale, fiecare nivel al ierarhiei
    acumuleaza caracteristicile claselor "parinte" si le adauga un anumit grad de
    specializare. Mai mult decat atat, in C++ este posibil ca o clasa sa
    mosteneasca simultan proprietatile mai multor clase, procedura numita
    mostenire multipla. Construirea ierarhiei de clase reprezinta
    activitatea fundamentala de realizare a unei aplicatii orientate obiect,
    reprezentand in fapt faza de proiectare a respectivului sistem.
    Sintaxa simplificata a derivarii este:

    class NumeClasaDerivata : NumeClasaDeBaza

    In continuare vom deriva din clasa Point o clasa specializata,
    GraphicPoint, care va "sti" sa deseneze efectiv punctul pe ecran:

    class GraphicPoint : Point
    {
    unsigned color;

    GraphicPoint(unsigned X, unsigned Y, unsigned Color);
    ~GraphicPoint();
    void Draw();
    void SetX(unsigned X);
    void SetY(unsigned Y);
    };


    GraphicPoint::GraphicPoint(unsigned X, unsigned Y, unsigned Color) :
    Point(X, Y)
    {
    color = Color;
    }


    GraphicPoint::~GraphicPoint()
    {
    }


    GraphicPoint::Draw()
    {
    // ...
    // apelare primitive grafice pentru desenarea efectiva a punctului
    }


    GraphicPoint::SetX(unsigned X)
    {
    Point::SetX(); // apelul functiei SetX() apartinand clasei de baza
    Draw();
    }


    GraphicPoint::SetY(unsigned Y)
    {
    Point::SetY();
    Draw();
    }



    Se observa din exemplul de mai sus ca am adaugat o variabila noua fata de
    clasa Point, color, pentru a putea memora culoarea cu care se face
    desenarea punctului. De asemenea, am suprascris constructorul si destructorul
    clasei parinte. In constructorul derivat, am apelat constructorul original
    folosind constructia:


    ClasaDerivata::ClasaDerivata() : ClasaDeBaza()


    In clasa GraphicPoint am adaugat o functie membra noua, Draw(),
    care deseneaza efectiv punctul pe ecran. Am suprascris functiile SetX() si
    SetY(), apeland in ambele functiile originale, utilizand sintaxa:


    ClasaDeBaza::FunctieMembra()


    apeland apoi functia de desenare, Draw().
    Regulile de functionare ale constructorilor si destructorilor, descrise
    in paragraful precedent, raman valabile si in cazul claselor derivate, cu doua
    observatii privind ordinea de apelare a acestora:
  • la instantierea clasei derivate, se apeleaza mai intai constructorul
    clasei de baza, apoi se apeleaza propriul constructor.
  • la distrugerea unui obiect al unei clase derivate, este apelat
    mai intai propriul constructor, si apoi destructorul clasei de baza (deci in
    ordine inversa crearii obiectului).


  • In capitolul urmator vor fi prezentate notiuni de programare avansata in
    C++, cum ar fi controlul accesului la clase, redefinirea operatorilor,
    mostenirea multipla si altele.
    ~thereau~
    ~thereau~
    *FondatoR*
    *FondatoR*

    Varsta: : 10/07/2010
    Localizare : Pascani/Iasi
    Mesaje : 563
    Credite : 1337
    Varsta : 32

    https://stargame.catsboard.com/forum.htm

    Sus In jos

    Sus


     
    Permisiunile acestui forum:
    Nu puteti raspunde la subiectele acestui forum