Object Oriented Programming
Object Oriented Programming
Cuprins:
Functii template
Clase template
De da structura de clase:
class Piesa
protected: char cod[4];
int pret;
class Piesa_A
int gauri;
class Piesa_B
char * culoare;
class Ansamblu
Piesa_A pa;
Piesa_B *vec;
int pret;
Obs:
1. dimensiunea lui vec este egala
cu numarul de gauri din pa
2. pretul este dat de suma
preturilor pieselor componente
Cerinte:
1. Realizati un vector care sa contina obiecte de tip: Piesa_A, Piesa_B si Ansamblu.
2. Sortati-l dupa pret
3. Parcurgeti-l si afisati toate atributele obiectelor.
(Tineti cont de regulile de buna implementare si reutilizare a codului!)
Observatii:
1. = > clasele Piesa si Ansamblu au nevoie de o interfata comuna (avem nevoie de o clasa
Object care contine numai metode virtuale pure).
2. =>avem nevoie de o metoda getPret - o putem declara virtuala pura in Object
3. =>avem nevoie de o metoda afisare - o putem declara abstracta in Object
#include <cstdlib>
#include <iostream>
#include <string.h>
using namespace std;
class Object
{ public:
virtual void afisare()=0;
virtual int getPret()=0;
virtual ~Object(){}
};
class Piesa: public Object
{ protected: char cod[4];
int pret;
public: Piesa(){}
Piesa(char c[4],int p)
{strcpy(cod,c);
pret=p;}
void afisare()
{cout<<"Cod: "<<cod<<endl;
cout<<"Pret: "<<pret<<endl;}
int getPret(){return pret;}
};
~Piesa_B() { delete[]culoare;}
void afisare()
{ Piesa::afisare();
cout<<"Culoare: "<<culoare<<endl;
cout<<"_________"<<endl;
}
};
int getPret()
{ pret=pa.getPret();
for(int i=0;i<pa.getGauri();i++)
pret+=vec[i].getPret();
return pret;
}
};
Exemplu: s-ar putea intr-o aplicatie sa avem nevoie de mai multe functii care sa
calculeze suma elementelor unor vectori; vectorii difera prin tipul de date stocate : int,
double, complex precum si prin dimensiune
int suma(int* vec,int dim)
{
int s(0);
return s;
return s;
} pentru cazul in care vectorul este de tip double
functia trebuie rescrisa (supraincarcata)
sau
class T
10
int main()
{
int n;
cin>>n;
Alt exemplu :
void afis(const int& x)
{
cout <<x<<endl;
}
Diferenta intre prototipuri este folosirea cuvintelor cheie: class, respectiv, typename.
Nu exista nicio deosebire intre cele doua forme.
template <class T, class U>
inline T getMin (T a, U b)
{
return (a<b?a:b);
}
//utilizare
int x=3;
double dd=3.10;
//pot preciza exact ce tipuri de date folosesc la apel
cout<<getMin<double,int>(dd,x); //functia e specializata pentru tipurile de date double
//si int
//sau, acelasi lucru:
cout<<getMin (dd,x); //functia e specializata pentru tipurile de date double si int
OBS:
La apelul unei functii template legarea se face in mod static.
Tipul unui parametru template este determinat in momentul compilarii => nu o sa putem
avea functii virtuale template.
//apel
cout<<" suma pt. vector de tip double cu dimensiunea 5: " << sum<double,5>(v) <<endl;
cout<<" suma pt. vector de tip int cu dimensiunea 10: "<< sum<int>(v)<<endl;
cout<<" suma pt. vector de tip int cu dimensiunea 10: "<< sum<>(v)<<endl;
cout<<" suma pt. vector de tip int cu dimensiunea 10: "<< sum(v)<<endl;
OBS: Nu toate compilatoarele permit tipuri default (Dev C++).
};
int main()
{
int v[10];
double v1[10];
float v2[10];
for (int i = 0; i<10; i++)
{ v[i]=i;
v1[i]=(double)i;
v2[i]=(float)i;
}
VectorInt vobj;
vobj.copie_cu_convesie(v);
vobj.copie_cu_convesie(v1);
vobj.copie_cu_convesie(v2);
system("PAUSE");
return 1;
}
#include <iostream>
using namespace std;
#include <math.h>
template <typename X, typename Y>
class pereche
{ X elem1;
Y elem2;
public:
pereche(const X &e1, const Y &e2)
{elem1=e1;
elem2=e2;
}
class complex
{ double re,im;
public:
complex(double r=0,double i=0){re=r;im=i;}
friend ostream& operator<<(ostream &d,complex x)
{ d<<x.re<<" j"<<x.im;
return d;
}
double getModul()
{ return sqrt(pow(re,2)+pow(im,2));}
};
int main()
{ pereche<int, double> p(4,3.00);
cout<<p;
complex x(1,1);
pereche<complex,double> p1(x,x.getModul());
cout<<p1;
system("PAUSE");
return 1;
}
Trebuie sa existe:
operator=, constructor fara
param., operator<< pentru
tipurile de date cu care se face
specializarea clasei pereche
int main()
{
pereche<int, double> p(4,3.00);
cout<<p.getElem1()<< ;
cout<<p.getElem2()<<endl;
cout<<p;
system("PAUSE");
return 1;
}
//destructor pt. T
//pentru a specializa clasa vector vom folosi tipurile: complex si punct si clasele derivate
class complex
{ double re,im;
public: complex(double =0,double =0);
friend ostream& operator<<(ostream &,complex );
}; //s-au generat automat operator=, constructor de copiere si destructor
class Punct
{ protected: double x,y;
public:
Punct(){}
Punct(double i,double j):x(i),y(j){}
friend ostream& operator<<(ostream &d,Punct * p) //va functiona doar pentru pointeri
{ p->afisare(d);
return d; }
friend ostream& operator<<(ostream &d, Punct & p)
{ p.afisare(d);
return d; }
virtual void afisare(ostream &d){
d<<"Perimetrul: "<<perimetrul()<<endl; d<<"Aria: "<<aria()<<endl; }
virtual double perimetrul()=0;
virtual double aria()=0;
virtual ~Punct(){}
}; //automat s-au generat operator=, constructor de copiere si destructor
int main()
{
int n;
cin>>n;
int *v=new int[n];
double *v1=new double[n];
complex *v2=new complex[n];
for (int i=0; i<n ;i++)
{ v[i]=i;
v1[i]=(double)i/2;
v2[i]=complex(i,i);
}
vector<int> vti(n,v);
cout<<vti<<endl;
vector<double> vtid(n,v1);
for (int i=0; i<vtid.getDim() ;i++)
cout<<vtid[i]<<" "<<endl;
vector<complex> vtic(n,v2);
cout<<vtic<<endl;
//vtic=vtid;
//no match for 'operator=' in 'vtic = vtid'
//candidates are: vector<T>&
//vector<T>::operator=(const vector<T>&)
//[with T = complex]
vector<complex> cv(vtic);
vtic=cv;
cout<<vtic;
Punct**vpc=new Punct*[2];
vpc[0]=new Cerc(0,0,3);
vpc[1]=new Dreptunghi(4,4,4,4);
vector<Punct*> vp(2,vpc);
cout<<vp;//acesta e motivul pentru care a
//trebuit implementat in ierarhia derivata
//din Punct operator<<
//Puteam face altfel?
system("PAUSE");return 1;
}
int main()
{
Der d(2,2); //Der nu e template
d.afis();
system("PAUSE");
return 1;
}
int main()
{
Der<int> d(2,2);
d.afis();
system("PAUSE");
return 1;
}
Der(int i, T j):Baza(i),a2(j){}
void afis() {
cout<<a1;
cout<<a2;
}
};
int main()
{
Der<int> d(2,2);//Der specializata pt int
d.afis();
system("PAUSE");
return 1;
}
};
template <typename T1,typename T>
class Der : public Baza<T>{
T1 a2;
public:
Der(T i, T1 j):Baza<T>(i),a2(j){}
void afis() {
cout<<Baza<T>::a1;
cout<<a2;
}
};
int main()
{
Der<int,int> d(2,2);
//Der e specializata pentru int si int
d.afis();
system("PAUSE");
return 1;
}
//constructor de copiere
typedef stack<int> STI; //tip de date STI: stiva specializata pentru int
int main(void)
{
stack<int> si;
//stiva specializata pentru int sau : STI si;
stack<char > ss; //stiva specializata pentru char
int a[3] = { 1, 2, 3,};
char s[3] = { 1, 2, 3};
for(int i = 0; i < 3; i++) {
si.push(a[i]); //populez stivele cu elemente
ss.push(s[i]);
}
stack<int> sj(si);
stack<char> st;
st = ss;
i = 0;
while (!sj.empty()) a[i++] = sj.pop(); //scot elementele din stiva si le pun in vector
i = 0;
while (!st.empty()) s[i++] = st.pop(); //scot elementele din stiva si le pun in vector
for(i = 0; i < 3; i++) cout << a[i] << " "; cout << "\n";
for(i = 0; i < 3; i++) cout << "\"" << s[i] << "\" ";
//ce se afiseaza?
Probleme:
1.Implementati clasa Poligon cu capacitati minime: constructori, operator=,
destructor, metoda de afisare, metoda calcul lungime (2 puncte consecutive ),
metoda de calcul a centrului.
Un poligon e descris de un vector de puncte.
Integrati clasa Poligon in ierarhia de figuri geometrice.