Sunteți pe pagina 1din 20

PARTICULARITILE

ELABORRII APLICAIILOR
C++
Croitor Mihail

Cuprins

Pointer la funcie
Motenire
Funcii virtuale

Polimorfism n baza funciilor virtuale


Clase abstracte

Redefinire operatorilor

Obiecte funcionale

abloane

Polimorfism static

Specializare abloanelor

Unele particulariti ale standardului C++11

Pointer la funcie

Pointer la funcie este un pointer, care conine


adresa punctului de ntrare n aceast funcie.
Declararea variabilei-pointer la funcie:
void (*pfunc)(double*, const size_t);

Declararea tipului pointer la funcie:


typedef void (*pfunc_t)(double*, const size_t);

Pointer la funcie:
exemplu
#include <stdio.h>
typedef void(*event_t)(void*,void*);
structButton{
size_tx,y,width,height;
chartext[255];
event_tOnClick;
};
voidButtonPressed(void*/*sender*/,void*/*arg*/){
puts("buttonpressed!");
}
intmain(){
Buttonbtn={5,5,75,30,"PressMe!",ButtonPressed};
btn.OnClick();
return0;
}

Motenire
Motenirea este un mecanism, care
permite descrierea clasei noi (clasa copil,
clasa derivat) n baza unei clase existente
(clasa de baz, clasa printe) cu pstrarea
funcionalitii clasei de baz.

Exemplu motenirii:
class Base {
int value;
public:
Base(): value(0){}
int getValue() { return value; }

Motenirea permite manipularea cu obiecte


de clasa derivata ca cu obiecte clasei de
baz.

};
class Derived: public Base{
public:

Pointer la obiectul clasei de baz poate


referi la obiectul clasei derivate. Afirmaie
invers este greit.

Derived() : Base() {}
void setValue(int data) {
value = data;
}
};

Motenire:
exemplu
class Entity{
protected:
std::string nam e;
Entity* parent;
public:
virtualstd::string ToString() const = 0;
Entity* G etParent() const{ return parent; }
};
class Folder: public Entity{
std::list< Entity*> childs;
public:
Folder(std::string n, Entity* p)
: nam e(n), parent(p){}
std::string ToString() const { return nam e; }
};

Funcii virtuale
Funcie virtual a clasei este o metod,
care poate fi redefinit n clasa copil i n
dependena de situaie se determin n
timpul executrii aplicaiei care
realizarea concret a funciei va fi
apelat.
Polimorfismul n baza funciilor virtuale
se numeste polimorfism dinamic.
Aceast proprietate printre altele permite
invocarea unei i aceleiai funciei (fr
redeclararea/redefinirea) cu parametrii
actuali de diferite tipuri.

Exemplu:
class Base{
public:
Base(): value(0){}
virtual void show() {
std::cout << "Base" << std::endl;
}
};
class Derived: public Base{
public:
Derived() : Base() {}
virtual void show() {
std::cout << Derived" << std::endl;
}
};

Funcii virtuale:
exemplu de polimorfism
class Base{
public:
Base(): value(0){}
virtual void show() { std::cout << "Base" << std::endl; }
};
class Derived: public Base{
public:
Derived() : Base() {}
virtual void show() { std::cout << "Derived" << std::endl; }
};
void print(Base* p) { p->show(); }
int main(){
Base* b = new Base();
Derived* d = new Derived();
print(b);
print(d);
return 0;
}

Funcii virtuale:
clase abstracte
O funcie virtuala poate fi declarata in clasa
fr definirea corpului ei. In acest caz
funcia se egaleaz cu zero si se
numete funcia virtual pur sau funcia
abstract. Daca o clasa conine cel puin o
funcie virtuala pura, atunci aceasta clasa se
numete clasa abstracta.
Orice funcie abstract se redefinete n
clasa-copil.
Clasele abstracte se utilizeaz n cazuri cnd
programator are nevoie de o mulime de
clase cu comportament comun.

structShape{
virtual voidDraw()=0;
virtual voidHide()=0;
};
structPoint:Shape{
virtual voidDraw(){
//drawthispoint
}
virtual voidHide(){
//hidethispoint
}
};

Clase abstracte sunt asemntoare


interfeelor din Java i C#

Redefinirea operatorilor
pentrucomoditate,esteutila
suprancrcarea(redefinirea)unui
operatorstandardpentruoclasa.
Programulinacestcazdevinemai
compactsimaiclar.
Formacomunapentru
supraincarcareesteurmatoarea:
<return_type>operator<operator
_sign>(<operator_parametres>);
pentru a determina locul de declarare a
operatorului- in cadrul clasei, sau in afara
ei - ntrebai-va, daca acest operator
schimba parametrii de intrare. Daca da,
atunci se recomanda declararea acestui
operator in clasa, dac nu, atunci mai bine
declarai-l in afara clasei.

lassint_pair{
intfirst,second;
public:
int_pair(intf=0,ints=0):first(f),
second(s){}
bool operator==(constint_pair&
p)const{
return(first==p.first)&&(second
==p.second);
}
};
bool operator!=(constint_pair&
p1,constint_pair&p2){
return!(p1==p2);
}

Obiecte funcionale
In declaraia clasei poate fi
suprancrcat operatorul (). Daca acest
operator este suprancrcat, atunci
obiectele acestei clase obin unele
proprieti ale funciilor (ele pot fi
utilizate in acelai mod ca si funcii).
Aceste obiecte se numesc obiecte
funcionale sau functori.
Utilizarea functorilor este comoda
atunci cnd funcia trebuie sa aib
"memorie", sau ca o alternativa
pointerilor la funcie.

//functorcaresocoatenumruldeapeluri
class_swap{
staticsize_tcounter=0;
static voidincrement(){++counter;}
public:
_swap(){}
void operator ()(int&a,int&b){
inttmp=a;
a=b;
b=tmp;
inc();
}
intgetNrCalls(){returncount;}
};
_swapswap;
inta=3,b=5;
swap(a,b);

abloane

ablonul clasei reprezint


un mecanism de generare a
familiei de clase cu
comportament comun
ablonul funciei
reprezint un mecanism de
generare a familiei de
funcii cu comportament
comun

template<classTYPE>
voidswap(TYPE&p1,TYPE&p2){
TYPEtmp=p1;
p1=p2;
p2=tmp;
}

Noiunea ablonul funciei deseori se


asociaz cu noiunea de algoritm.

abloane:
polimorfism static
int main(){
inti1=3,i2=5;
floatf1=1.2,f2=2.3;
doubled1=1.003,d2
=10;
swap(i1,i2);
swap(f1,f2);
swap(d1,d2);
return0;
}

n exemplu dat, una si aceeai


denumirea funciei este
utilizata cu tipuri de date
diferite. Aceasta proprietate,
realizat cu ajutorul
abloanelor, se numete
polimorfism static, deoarece
determinarea comportamentului
funciei are loc la etapa de
compilare a programului.

abloane:
specializarea abloanelor
Pentru un tip de date
concret poate fi definit o
versiune special a
ablonului.

template<>
void swap(int* a, int* b){
int tmp = *a;
*a = *b;
*b = tmp;
}

Dac un ablon (i/sau specializarea lui)


nu se utilizeaz n codul surs atunci la
etapa de compilare el nu se include n
codul binar!

++11: tipuri automate


Cuvntul cheie auto
spune compilatorului
s determine tipul
variabilei in mod
automat, dup valoare
autoval=5;

++11: iniializatori
A aprut posibilitatea
iniializrii claselor
containeri cu ajutorul
listelor de iniializare.

classArray10{
int_val[10];
public:

Array10(std::initializer_list<i
nt>list);
};
Array10a=
{1,2,3,4,5,6,7,8,9,0};

++11: lambda-funcii
Expresii lambda permit
programatorilor s
accelereze scrierea
codului. Sub expresii
lambda neleg un mod
special de definirea
functorilor.

[](intx,inty){returnx+y;}
//,[](intx,inty)->
int{intresult=x+y;return
result;}
structsum{
intopertator()
(intx,inty){returnx+y;}
};

C++11: pointer nul


Utilizarea valorii 0 ca
pointer nul n unele
cazuri aducea la cod
periculos. Se recomand
utilizarea cuvntului
cheie nullptr.

void test(int);
void test(char*);
int main(){
test(0); // ???
test(nullptr); // !!!
return true;
}

++11: bucl pentru fiecare


inta[5]={1,2,3,4,5};
for(auto&el:a){
++el;
}
for(autoel:a){
std::cout<<el<<"";
}

Standard nou ++ propune o


form nou de bucla for:
for( type element: collection)
{}

Mulumesc de atenie!