Documente Academic
Documente Profesional
Documente Cultură
ELABORRII APLICAIILOR
C++
Croitor Mihail
Cuprins
Pointer la funcie
Motenire
Funcii virtuale
Redefinire operatorilor
Obiecte funcionale
abloane
Polimorfism static
Specializare abloanelor
Pointer la funcie
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; }
};
class Derived: public Base{
public:
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
}
};
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
template<classTYPE>
voidswap(TYPE&p1,TYPE&p2){
TYPEtmp=p1;
p1=p2;
p2=tmp;
}
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;
}
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;
}
++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;}
};
void test(int);
void test(char*);
int main(){
test(0); // ???
test(nullptr); // !!!
return true;
}
Mulumesc de atenie!