Documente Academic
Documente Profesional
Documente Cultură
Cursul 1
Scurt introducere n POO
clase i obiecte
atribute, metode, stri
ascunderea informaiei, ncapsulare
declararea claselor i obiectelor n C++
constructori i destructori
exemplu clasa Cont
Tipuri abstracte de date clase si obiecte
exemplu clasa Stiva
Utilizarea bibliotecilor de clase
stringuri definite de utilizator
din clasa string a STL
Ce este C++
Este un C mai bun;
Programatorii buni in C au un dezavantaj: au tendina sa
scrie cod C++ in stilul C pierznd beneficiile aduse de C++
Suport abstractizarea datelor
Suport programare orientat obiect
Suport programare generic
C++ nu a fost proiectat s impuna un anume stil de
programare, el suporta stilurile (paradigmele) tradiionale i
pe cele avansate:
Programare procedural: Decide ce proceduri sunt
necesare, si alege cei mai buni algoritmi pentru ele
Programare modular: Decide ce module sunt necesare,
mparte programul asa fel incat datele sa fie ascunse n
module
Tipuri abstracte de date (Tipuri definite de utilizator):
Decide ce tipuri ii sunt de folos si construiete cte un set
complet de operaii pentru acestea
Clasa cont
Specificarea clasei
Un cont bancar:
are un titular, sold, o rat a dobnzii, numar de cont
se pot efectua operaii de depunere, extragere, actualizare
sold
Extragerea atributelor:
titular, sold, rat a dobnzii, numr de cont
Extragerea metodelor:
depunere, extragere, actualizare sold
Completare specificaie
actualizare sold data ultimei operaii
Clase - proiectare
Definiia unei clase presupune:
combinarea datelor cu operaiile ce se aplic acestora
ascunderea informaiei
ASCUNDERE i NCAPSULARE
Ascunderea informaiei:
Modul de structurare a datelor nu este cunoscut: datele
sunt declarate intr-o seciune privat a clasei.
Accesul la date, pentru consultare, modificare, etc. se face
numai prin intermediul funciilor clasei: acestea sunt
declarate intr-o seciune public a clasei interfaa clasei.
Pot exista date publice precum si funcii private:
decizia este a programatorului.
ncapsulare = Combinare + Ascundere
Datele si funciile (operaiile) care pot aciona asupra
datelor sunt incluse n aceeai unitate sintactic
n C++ acest lucru se realizeaza prin tipul utilizator struct
sau class
AVANTAJE
Combinarea datelor:
definete clar ce structuri de date sunt manevrate i
care sunt operaiile legale asupra lor.
programul capt modularitate.
public:
// Declaratii functii (eventual date)
protected:
// Declaratii date (eventual metode)
private:
// Declaratii date (eventual metode)
};
Exemplu
//FILE stiva1.h
class Stack {
public:
enum { MaxStack = 50 };
void init() { top = -1; }
void push( int ) ;
int pop() ;
bool isEmpty() { return top < 0; }
bool isFull() { return top >= MaxStack - 1; }
void print() ;
private:
int top;
int arr[ MaxStack ];
};
Exemplu
//data.h
#include <iostream>
using namespace std;
class Data {
public:
Daitnat(iunnt_aon_z=i a=n _zciu_rceunrte(n)t)a;(), int
o_luna = luna_curenta(),
~Data() {}
void aduna_zi(int n);
void aduna_luna(int n);
Exemplu
int get_zi() const;
int get_luna() const;
int get_an() const;
friend ostream& operator<<(ostream&, const Data&);
static Data azi();
private:
int zi, luna, an;
static int zi_curenta();
static int luna_curenta();
static int an_curent();
bool esteAnBisect();
int NrZileLuna();
int NrZileAn();
};
OBIECTE - Declaraie
Declaraie obiecte:
<Nume_clasa> <Nume_Obiect>,C ;
<Nume_clasa> <Nume_Obiect>(<Parametri_actuali>);
La declararea unui obiect:
Se aloc memorie pentru datele membru
Se execut o metod constructor
La ieirea dintr-un bloc
Se apeleaz destructorul (este unic) pentru fiecare din
obiectele locale ce nceteaz s mai existe
OBIECTE - Declaraie
Data d1; // Apel constructor d1.Data()
Data d2(5,3,2007);
// Apel constr. Data(int,int,int)
Data d3[5];// Apel constructor Data() de 5 ori
Obiecte dinamice:
Data *pd = new Data; // apel constructor pd->Data()
Data *t = new Data[5];// apel de 5 ori t->Data()
delete pd; // se apeleaza pd->~Data()
delete [] t; // se apeleaza t ->~Data() de 5 ori
Exemplu
#include <iostream>
using namespace std;
class C
{
public:
C(){cout << "C() ";}
~C(){cout << "~C() ";}
private:
int i;
};
int main(){
C c1;
C* p1= new C;
{
C c[2];
C* p2 = new C;
delete p2;
}
C c[2];
delete p1;
return 0;
}
//C() C() C() C() C() ~C() ~C() ~C() C() C() ~C() ~C() ~C()
~C()
CLASE - Implementare
Funcii membru(Metode) - Implementare:
n cadrul clasei implementarea se face, n general, inline
n afara clasei (precedat de inline pentru implementare
inline):
<tip> <Nume_clasa>::<Nume_functie>(<Lista_parametri>)
{
// Corp functie
}
void Data::aduna_luna(int n){
int l = luna + n;
if (l > 12)
{
luna = l % 12;
if (luna == 0) luna = 12;
an += (l - luna)/12;
}
else
luna = l;
}
inline void Data::set_an(int an_nou){an = an_nou;}
CLASE - Mesaje
Apel(Invocare) funcie membru (Mesaj ctre obiect):
<Nume_obiect>. <Nume_functie>(Lista_par_act)
<Nume_point_obiect> -> <Nume_functie>(Lista_par_act)
(*<Nume_point_obiect>). <Nume_functie>(Lista_par_act)
Data *pd, azi,maine (26,3,2007);
azi.set_an(2007);
azi.set_luna(3);
azi.set_zi(5);
pd = &azi;
pd->get_zi();
(*pd).get_zi();
Funcii manager: constructori, destructor
Data(int, int, int), Data(int, int),
Data(int), Data(), Data(const char*)
~Data()
Funcii de acces:
Data::get_zi(), Data::set_an()
Implementori:
void Data::aduna_zi()
Operatori :
Data& Data::operator++()
Funcii ajuttoare:
bool Data::esteAnBisect(){
return (an%400==0)||((an%4==0)&&(an%100!=0));
}
Funcii membru const (nu modific starea obiectului):
int Data::get_zi() const {return zi;}
int Data::get_an() const {return an++;}//Eroare!
CLASE Metode const
O funcie membru const poate fi apelat att pentru
obiecte const ct i pentru obiecte non - const;
O funcie membru non - const nu poate fi apelat pentru
obiecte const!
Exemplu
void f(Data& d, const Data& cd){
int i = d.get_an();
d.aduna_an(2);
int j = cd.get_an();
cd.aduna_an(1); // Eroare: cd este obiect const!
//O
}
const face parte din tipul metodei, la implementarea n
afara clasei trebuie precizat acest lucru:
inline int Data::get_an() const{
return an;
}
CLASE - Pointerul implicit this
Pentru fiecare funcie membru exist o singur instan
care este accesibil fiecrui obiect
Pointerul this pointer implicit accesibil doar n funciile
membru ale unei clase (structuri); pointeaz la obiectul
pentru care este apelat funcia
int get_luna() const {return this->luna;}
int get_luna(Data* d )const {return d->luna;}
Data azi(5,3,2007);
cout << azi.get_luna() << endl;
cout << azi.get_luna(&azi) << endl;
(*this) pentru (returnarea) obiectul(ui) curent ntr-o funcie
membru
Constructorii unei clase
void Data::init(int z, int l, int a)
{zi = z; luna = l; an = a;}
Data d; d.init(5,3,2007);
Constructor: o funcie membru cu misiunea de a iniializa
obiectele declarate. Dac o clas are constructori, obiectele
clasei sunt iniializate la declarare.
Data azi(2);
Data maine(3, 4);
Data acum;
Data Craciun(25 Decembrie);
}
//Clasa cont - implementare
Cont::Cont()
{
titular = NULL;
dataUltOp = NULL;
sold = 0;
rataDob = 0;
atribuieNrCont();
}
Cont::~Cont()
{
delete titular;
delete dataUltOp;
}
void Cont::depune(double suma)
{
sold += suma;
}
void Cont::extrage(double suma)
{
actualizeazaSold();
if(suma > sold)
throw "Sold insuf.";
sold -= suma;
}
Clasa cont - utilizare
void main()
{
Cont cont;
cont.depune(2000);
}
cont.sold += 2000;
error C2248: 'sold' : cannot access private
member declared in class 'Cont'
Utilizarea de clase
exist multe bibloteci de clase
STL
MFC
etc
pentru utilizare, trebuie cunoscut doar interfaa
(elementele publice)
nu intereseaz implementarea
programul care utlizeaz clasa este independent de
implementarea clasei
Exemplu: string
my-string.h
STL
// my_string.h
class string
{
public:
// Constructori/destructori
string();
string(char* new_string);
string(const string& new_string);
...
~string();
Utilizarea de clase
// Operatori
friend string operator+ (const string& lhs, const string&
rhs);
string& operator+= (const string& a_string);
string& operator= (const string& a_string);
friend bool operator< (const string& lhs, const string&
rhs);
friend bool operator> (const string& lhs,
const string& rhs);
friend bool operator== (const string& lhs, const string&
rhs);
Cont versiunea 2
// cont.h char* ==> string
#include <string>
using namespace std;
class Cont
{
public:
Cont();
Cont(string nume, double soldInit);
~Cont();
void depune(double);
void extrage(double);
void setDob(double);
private:
string titular;
string nrCont;
double sold;
double rataDob;
string dataUltOp;
void actualizeazaSold();
void atribuieNrCont();
}
// cont.cpp
#include "cont.h"
Cont::Cont()
{
dataUltOp = "";
sold = 0;
atribuieNrCont();
}
Cont::Cont(string nume, double soldInit) : titular(nume),
sold(soldInit)
{
// dataUltOp = azi();
}
void Cont::depune(double suma)
{
sold += suma;
// demo.cpp
#include "cont.h"
void main()
{
Cont cont("Ionescu", 10000);
cont.extrage(2000);
}
Funcii: suprancarcare
C++ dispune de un mecanism de verificare a tipului mult
mbunatit fa de C.
Ca i n viaa real, nelesul unui cuvnt poate fi dedus
din context
Utilizarea aceluiai cuvnt cu nelesuri diferite
suprancrcare (overloading)
n loc de a folosi, de pild print_char(),print_int(),
print_float(), folosim print(char), print(int), print(float)
Numele funciilor pot fi suprancrcate: mai multe funcii, n
care numrul i/sau tipul parametrilor difer, pot avea
acelai nume:
int f(int x, int y){return x*y;}
double f(int x, int y){return x*y;}
int f(double x, int y){return x+y;}
void main(){
cout << f(5.3, 3)<< ' ';
cout << f(2.f,3)<< ' ';
cout << f(2,3) << ' ';
}
// 8 5 6
Funciile suprancrcate pot aparine i unei clase:
void f();
class X { void f();}
Funciile cu acelai nume nu pot diferi doar prin tipul
returnat:
double f(int);
int f(int); // eroare pentru ca f(40) este ambiguu
Constructorii unei clase sunt funcii suprancrcate
Parametrii funciilor pot avea valori implicite:
void add3(int& s, int a, int b, int c = 0){
s = a + b + c;
}
add3(s1, 3, 5, 9);
add3(s2, 5, 6);
Atenie la ambiguiti (suprancrcare + parametri
implicii):
int f(int x = 0, int y = 0);
double f(int z);
// apelul f(7) este ambiguu!
Suprancarcare operatori 1
O nou modalitate de a apela o funcie
Se pot suprancarca operatorii existeni, cu excepia
operatorilor:
:: Operatorul de rezoluie
. Operatorul de selectare a membrilor
.* Operatorul de selectare prin pointeri la funcii
Nu pot fi introdui operatori noi
Nu pot fi schimbate: precedena i asociativitatea
}
#include <stdio.h>
class Point
{
protected:
unsigned x, y;
public:
Point();
Point(Point &p);
Point(unsigned X, unsigned Y);
~Point();
unsigned long Arie();
unsigned GetX();
unsigned GetY();
void SetX(unsigned X);
void SetY(unsigned Y);
Point& operator += (Point __p);
Point& operator -= (Point __p);
Point operator + (Point __p);
Point operator - (Point __p);
Point& operator = (Point __p);
int operator == (Point __p);
int operator != (Point __p);
int operator < (Point __p);
int operator > (Point __p);
int operator <= (Point __p);
int operator >= (Point __p);
};
Point::Point()
// constructor implicit
{
x = 0;
y = 0;
}
Point::Point(unsigned X, unsigned Y)
{
x = X;
y = Y;
}
Point::Point(Point &p)
{
x = p.x;
y = p.y;
}
Point::~Point()
{
}
unsigned Point::GetX()
{
return x;
}
unsigned Point::GetY()
{
return y;
}
void Point::SetX(unsigned X)
{
x = X;
}
void Point::SetY(unsigned Y)
{
y = Y;
}
unsigned long Point::Arie()
{
return this->x * this->y;
}
Point& Point::operator += (Point __p)
{
x += __p.x;
y += __p.y;
return *this;
}
Point& Point::operator -= (Point __p)
{
x -= __p.x;
y -= __p.y;
return *this;
}
Point Point::operator + (Point __p)
{
return Point(x + __p.x, y + __p.y);
}
Point Point::operator - (Point __p)
{
return Point(x - __p.x, y - __p.y);
}
int Point::operator == (Point __p)
{
return x == __p.x && y == __p.y;
}
int Point::operator != (Point __p)
{
return !(*this == __p);
}
int Point::operator < (Point __p)
{
Alocare dinamic
Operatorul new:
Alocare de obiecte simple:
new tip;
new tip(parametri);
int* pi = new int;
complex* pc = new complex(2., 3.);
string *pstr = new string(Sir alocat dinamic);
Alocare de tablouri de obiecte:
new tip[O];
Se apeleaz constructorul implicit
double* pt = new double[5];
string *ptstr = new string[30];
int const* q = new int[10];// *q este const
const int* q = new int[10];// la fel
int* const q = new int[10];// q este const
Alocare dinamic
Operatorul delete:
Dealocare obiecte simple:
delete pointer;
delete pi;
Dealocare tablouri de obiecte:
delete []pointer;
delete []pt;
delete []ptstr;
Pentru tipurile utilizator(clase) la execuia operatorului
delete se apeleaz destructorul clasei
Exemplu:
struct matrice {
tip (Nume_clasa::*point_func)(parametri);
tip (Nume_clasa::*point_func)(parametri) =
&Nume_clasa::Nume_metoda;
Utilizare:
(obiect.*point_func)(parametri);
(point_obiect ->*point_func)(parametri);
Un pointer la o funcie membru, cand se instantiaza,
trebuie s se potriveasc cu functia respectiva n trei
elemente:
numrul i tipurile argumentelor
tipul valorii returnate
tipul clasei a crei membru este
//Pointeri la functii membru
class C{
public:
void f(int n=5) const {cout << "apel C::f(" << n <<")" <<
endl;}
void g(int n) const {cout << "apel C::g(" << n <<")" <<
endl;}
void h(int n) const {cout << "apel C::h(" << n <<")" <<
endl;}
void i(int n) const {cout << "apel C::i(" << n <<")" <<
endl;}
};
void main(){
C c;
C* pc = &c;
void (C::*p_metoda)(int=0) const = &C::h;
(c.*p_metoda)(7);
(pc->*p_metoda)();
p_metoda = &C::f;
(pc->*p_metoda)(8);
(c.*p_metoda)();
c.f();
}
// apel C::h(7) apel C::h(0) apel C::f(8) apel C::f(0) apel
C::f(5)
Exemplu
Atenie la declararea pointerilor
class Ex{
public:
int fct(int a, int b){ return a+b;}
};
//typedef int (Ex::*TF)(int,int);
typedef int (*TF)(int,int);
void main(){
Ex ex;
TF f = Ex::fct; // eroare: f nu e pointer
// al clasei Ex
cout << (ex.*f)(2,3) << "\n";
}
Operatorii binari se definesc fie ca funcii membru nestatic
cu un argument sau funcii
nemembru cu 2 argumente
Suprancarcare operatori: operator@
Operatorii unari se definesc fie ca funcii membru nestatic
fr argumente (cu un argument int pentru postfix) sau
funcii nemembru cu 1 argument (2 argumente postfix);
operator=, operator[], operator() i
operator-> trebuie definii ca funcii membru nestatic; asta
asigur c primul operand este lvalue
Suprancarcare operatori
operator<< i operator>> nu pot fi definite ca metode; n
std sunt definii aceti operatori i redefinirea ca metode ar
nsemna modificarea claselor din std ceea ce este imposibil;
int main(){
Cstring p1("Popescu Ion"), p2("Ionescu Paul");
cout << " \nSirul p1 folosind operator[] : ;
cout << endl;
for ( int i = 0; i < p1.get_lung(); i++)
cout << p1[i];
p1 = p2;
cout << " \nNoul sir p1 folosind operator[]: ;
cout << endl;
for ( i = 0; i < p1.get_lung(); i++)
cout << p1[i];
return 0;
}
Operator () Obiecte funcii
class Matrice{
public:
enum { max_Size = 20};
Matrice(int s1, int s2) :size1(s1), size2(s2){}
int& operator()(int, int);
int get_s1(){return size1;}
int get_s2(){return size2;}
private:
int a[max_Size];
int size1,size2;
};
int& Matrice::operator()(int i, int j){
if(i < 0 || i >= size1)
throw "Primul indice gresit\n";
if(j < 0 || j >= size2)
throw "Al doilea indice gresit\n";
return a[i*size2 + j];
}
int main(){
Matrice a(3, 4);
int i, j;
for (i = 0; i < a.get_s1(); i++)
for(j =0; j < a.get_s2(); j++)
a(i, j) = 2*i + j;
for (i = 0; i < a.get_s1(); i++) {
for(j =0; j < a.get_s2(); j++)
cout << a(i, j) << " ";
cout << endl;
}
try{
cout << a(1, 2) << endl;
cout << a(2, 8) << endl;
}
catch(char* s){cout << s ;}
return 0;
}
/*
0123
2345
4567
4
Al doilea indice gresit
*/
CLASE: Suprancrcare operatori
Minimizarea numrului funciilor ce au acces direct la
reprezentare:
Operatorii ce modific valoarea primului argument, ca
membri (ex. +=)
Operatorii ce produc noi valori, ca funcii externe (ex. +, -,
)
class complex{
public:
complex& operator+=(const complex a);
//O
private:
double re, im;
};
inline complex& complex:: operator+=(const complex
a){
re += a.re; im += a.im; return *this;
}
complex operator+(complex a, complex b){
complex s = a;
return s+= b;
}
CLASE: Constructor de conversie
Constructorul de conversie definete o conversie(ce se
aplic implicit) de la un tip (de baza) la un tip utilizator
X::X(tip_de_baza m)
};
void f(Orange) {}
int main() {
Apple a;
f(a);
}
//error C2664:'f' : cannot convert parameter 1 from
//'class Apple' to 'class Orange'
CLASE: Conversie
Ambiguitate operatori conversie/suprancrcare funcii:
class Orange {};
class Pear {};
class Apple {
public:
operator Orange() const; // conversie Apple -> Orange
operator Pear() const; // conversie Apple -> Pear
};
// Supraincarcare eat():
void eat(Orange);
void eat(Pear);
int main() {
Apple c;
eat(c); // Error: Apple -> Orange or Apple -> Pear ???
}
Clase parametrizate
Programare generic : programare ce utilizeaz
tipurile ca parametri
n C++ - mecanismul template: clase template,
funcii template
Programatorul scrie o singur definiie template
iar C++, pe baza parametrilor, genereaz
specializri care sunt compilate cu restul
programului surs
private:
Elt* val;
};
template <class Elt>
Cell<Elt>::Cell()
{
val = new Elt;
template <class Elt>
Cell<Elt>::Cell(const Cell<Elt>& c)
{
val = new Elt;
*val = *(c.val);
}
template <class Elt>
Cell<Elt>::~Cell()
{
delete val;
}
template <class Elt>
Cell<Elt>& Cell<Elt>::operator =(const Cell<Elt>& c)
{
*val = *(c.val);
return *this;
}
#include "cell.h"
template <class Elt>
class Array
{
public:
Array(int = 1);
Array(const Aray&);
~Array();
Elt get(int);
}
// pentru a sorta tablouri de celule de int-uri
// trebuie definit operatorul de comparare:
bool operator >(const Cell<int>& x, const Cell<int>& y)
{
return x.getVal() > y.getVal();
}
// sortare prin insertie
template <class T>
void insert_sort(Array<T>& a, int n)
{
int i,j;
Cell<T> temp;
for(i=1;i<n;i++) {
temp = a[i];
j=i-1;
while((j >= 0) && (a[j] > temp)) {
a.set(j+1, a[j].getVal());
j--;
}
if (i != (j-1))
a.set(j+1, temp.getVal());
}
}
typedef Cell<int> Int;
typedef Cell<char> Char;
Clase parametrizate - Exemplu 2
template <class T>
class Vector
{
public:
Vector(int=0);
T& operator [](int);