Sunteți pe pagina 1din 10

Ministerul Educaiei al Republicii Moldova

Universitatea Tehnic a Moldovei


Catedra Automatica si Tehnologii Informationale

RAPORT
Lucrarea de laborator nr.7
Tema: Sabloane
Varianta 10

A efectuat:
st. gr. SI-141

E. Cucu

A verificat:
Lector universitar

M. Balan

Chiinu 2015

Scopul lucrrii:
Studierea necesitii abloanelor;
Studierea regulilor de definire i utilizare a abloanelor;
Studierea specializrii abloanelor;
Studierea potenialelor probleme rezolvate cu ajutorul abloanelor;

Indicatii teoretice:
abloanele reprezint cea mai puternic construcia a limbajului C++, dar n acelai
timp, unul din cele mai puin studiate i rar utilizat. Cauza este ascuns n faptul c el este
foarte complicat i are o sintax neobinuit.
Aa deci, abloanele reprezint prin sine un mecanism ce permite s scrii un algoritm,
care nu este legat de un tip anumit. Cel mai des, abloanele sunt utilizate pentru crearea
container i algoritmi abstraci. Containerele sunt obiecte, care conin alte obiecte sau date,
cel mai des o cantitate nedeterminat, aa cum sunt masivele, stivele, liste asociative, etc.
Prin algoritm abstract este necesar de neles studierea bun a metodelor de prelucrare a
datelor, ca sortarea, cutarea, etc., nscrise fr prezentarea tipului datelor.
abloanele sunt clase i funcii. abloanele au venit sa schimbe macrourile, aa cum
ultimele foarte des duc la gsirea complicat a erorilor, deoarece compilatorul nu verific,
dar nici nu are posibilitatea s le verifice de erori sintactice.
Programatorul, scriind abloanele, creeaz aprovizionarea, care, ca urmare, se
utilizeaz deja cu tipurile de date specificate. Adic, la baza abloanelor compilatorul creeaz
funcii normale. Dac abloanele sunt utilizate cu cteva tipuri de date diferite, compilatorul
creeaz un codul necesar pentru fiecare tip n parte. Cu alte cuvinte, abloanele nu
micoreaz compilarea modulului, mai degrab chiar invers, dar simitor micoreaz codul
de ieire, care duce la, micorarea cantitii de erori, micoreaz introducerea modificrilor
n cod i micoreaz prezentarea programelor n general, aa cum se micoreaz calitatea
tipurilor i funciilor date.
Definirea
abloanele sunt definite cu ajutorul cuvntului rezervat template:
template <class T>
T& searchmax(T* ptr, int size);
Template <class T>
class Stack{
T mas[10];
public:
...
};
Din exemplu se vede specificul definirii ablonului, pentru crearea lui este necesar de
prezentat template, n paranteze unghiulare cuvntul class1 i un tip abstract, care se va
1

n corespundere cu noile standarde, la fel poate fi utilizat typename n locul class.

utiliza n definirea ablonului. Istoric aa sa ntmplat, c cel mai des, se utilizeaz


identificatorul T, de la cuvntul type. Pentru clas, la definirea funciilor n afara clasei,
nainte de fiecare funcie este necesar de scris, din nou, cuvntul template.
Utilizarea
Funciile se utilizeaz practic aa ca i funciile obinuite.
void main(){
int
masi[10];
float masf[20];
cout<<searchmax(masi,10);
cout<<searchmax(masf,20);
}

Se vede c, sintaxa, apelrii coincide cu cele obinuite. Cunoscnd tipurile parametrilor


funciilor, compilatorul genereaz funcii obinuite. Dup care are posibilitatea s suprancarce
funcia. n cazul claselor lucrurile sunt puin mai complicate:
void main(){
Stack<int>
Stack<float>
}

sti;
stf;

Este necesar de prezentat tipul datelor, aa cum, n acest caz, la aceast etap de translare,
compilatorul nu este n stare s determine, pentru care tip de date este necesar de generat codul.
Specializarea
Cte odat nu ne satisface lucrul abloanelor pentru determinarea tipurilor datelor. Ca de
exemplu:
template <class T>
T& max(T& a, T& b){
if(a>b)return a;
return b;
}

Acest exemplu lucreaz excelent pentru tipurile ncorporate, aa ca int, float i altele.
Dar pentru iruri nu. Motivul const n aceia, c n acest caz se vor compara pointerii la iruri,
dar nu coninutul irului. Pentru alte tipuri de date, posibil nu este definit operatorul >.
Rezolvri pot fi cteva: se poate de interzis utilizarea pointerilor la iruri i s utilizezi tipul
String, pentru care este definit operatorul >, atunci n acest caz se complic procesul de
dezvoltare i regulile de utilizare. Mai mult ca att, interzicerea poate fi numai informativ,
adic dac utilizatorul tie, c nu trebuie de utilizat pointeri. nsi limbajul nu are posibilitatea
s interzic utilizarea specificrii unui tip de date special. Alt rezolvare const n utilizarea
specializrii, care reprezint nscrierea nc a unei funcii pentru un tip determinat. n cazul
funciilor aceast de obicei nu este o funcie ablon cu acelai nume i cu parametri predefinii.
Aceast funcie poate avea un avantaj mai mare dect abloanele. n cazul claselor se poate
desigur de definit o clas neablon cu acelai nume, dar aceasta nu este interesant, aa cum
deosebirile pot fi minimale. n acest caz poate fi utilizat specializarea metodei clasei.
Specializat poate fi numai metoda definit n afara clasei. Ca de exemplu:
template <class T>

class Stack{
public:
void push(T& t);
void sort();
friend ostream& operator<<(ostream& os, Stack<T>& s);
};
template <class T>
void Stack<T>::sort(){
...
// aici se nscrie un algoritm abstract
}
void Stack<char*>::sort(){
... // dar aici unul specializat
}
template <class T>
ostream& operator<<(ostream& os, Stack<T>& s){
return os; // afiarea coninutului stivei
}
void main(){
Stack<int> si;
si.push(5);
Stack<char*> sc;
sc.push("Hello");
si.sort();
// Apelarea funciei abstracte
sc.sort();
//Apelarea funciei specializate
cout<<si<<sc;
// Apelarea operatorului de suprancrcare a fluxului de ieire
}

abloanele clasei pot fi motenite, aa ca i cele obinuite, cu aceasta, i acel de baz,


aa i a cel derivat pot fi clase obinuite.
class One{
};
template <class T>
class Two: public One{
};
template <class T>
class Three: public Two<T>{
};
class Four: public Three<int>{
};
template <class T>
class Five: public T{
};

Un interes deosebit reprezint prin sine ultimul tip de motenire, aa cum are loc
motenirea de la parametrii ablonului. n acest caz T desigur nu trebuie s fie clas ori
structur.
Cum se vede din cele relatate mai sus, abloanele reprezint prin sine un mecanism
interesant i puternic. Sunt greuti i complicaii n studierea lor, dar ele se rscumpr, aa
cum permit crearea unui cod frumos i compact. Mai mult ca att, abloanele nu sunt realizate
n alte limbaje de programare moderne utilizate pe larg, dar la fel permit realizarea unor noi
rezolvri tehnice, aa cum pointeri detepi, susinerea tranzaciei, dirijarea memoriei, etc.

Sarcina lucrarii:
) Creai o funcie ablon, de sortare a elementelor unui masiv n descretere prin metoda
de introducere. Funcia trebuie s lucreze cu masive de lungimi diferite.
b) Creai clasa parametrizat MultiMap list multi-asociativ, care conine cheia
cmpurilor i lista de valori. Adic, unei chei pot sa-i aparin mai multe valori. Clasa
trebuie s conin constructorii, destructorii i funciile add, removeByKey, getLength,
getByKey, getByValue, i operatorii [] i de intrare/ieire.

Listingul programului:
a)Functia parametrizata sortTab
Fisierul main.cpp
#include <iostream>
#include <stdlib.h>
using namespace std;
template <typename T>
void sortTab(T* array,int numElem);
int main() {
int intTab[10] = {5,6,3,10,45,33,2,0,5,87};
float floatTab[10] = {1.2,5.1,20.6,5.1,1.1,0.3,0.7,12.3,3.2,20.1};
double doubleTab[10] = {1.20,0.20,12.36,25.36,2.15,3.14,25.3,14.25,1.21,5.21};
char charTab[10] = {'v','A','b','f','r','y','e','g','o','m'};
cout << "Before Sort : " << endl;
cout << "intTab : ";
for (auto item : intTab) {
cout << item << " ";
}
cout << endl;
cout << "floatTab : ";
for (auto item : floatTab) {
cout << item << " ";
}
cout << endl;
cout << "doubleTab : ";
for (auto item : doubleTab) {
cout << item << " ";
}
cout << endl;
cout << "charTab : ";
for (auto item : charTab) {
cout << item << " ";
}
sortTab(intTab,10);
sortTab(doubleTab,10);
sortTab(floatTab,10);
sortTab(charTab,10);
cout << endl << "After Sort : " << endl;
cout << "intTab : ";
for (auto item : intTab) {

cout << item << " ";


}
cout << endl;
cout << "floatTab : ";
for (auto item : floatTab) {
cout << item << " ";
}
cout << endl;
cout << "doubleTab : ";
for (auto item : doubleTab) {
cout << item << " ";
}
cout << endl;
cout << "charTab : ";
for (auto item : charTab) {
cout << item << " ";
}
cout << endl;
system("pause");
return 0;
}
template <typename T>
void sortTab(T* array,int numElem) {
T swap;
for (int i = 0; i < (numElem - 1); i++) {
for (int j = 0; j < numElem - i - 1; j++) {
if(array[j] < array[j+1]) {
swap = array[j];
array[j] = array[j+1];
array[j+1] = swap;
}
}
}
}

b) Clasa parametrizata MultiMAP


Pentru interpretarea clasei parametrizate MultiMap am construit o clasa DynArray
care reprezinta un tablou dynamic pentru pastrarea cheilor si valorilor utilizate pe
viitor in MultiMap.
Fisierul DynArray.h
/
// Created by JACK on 11/18/2015.
//
#ifndef CEF07B_DYNARRAY_H
#define CEF07B_DYNARRAY_H
#include <iostream>
#include <cstdlib>
using namespace std;
template <typename T>
class DynArray{
private:

T* array;
int length;
int nextIndex;
public:
DynArray(){
array = new T[1];
length = 1;
nextIndex = 0;
}
~DynArray(){
if(array)
delete[] array;
}
void setVal(int index, T val){
array[index] = val;
}
void clear(){
delete []array;
array = new T[1];
length = 1;
nextIndex = 0;
}
int getLength(){
return length;
}
int getNextIndex(){
return nextIndex;
}
T getIndex(int index){
return array[index];
}
bool isIn(T val){
for(int i = 0; i <length; i++){
if(val== array[i]){
return true;
}
}
return false;
}
int indexofVal(T val){
for(int i = 0; i <length; i++){
if(val == array[i]){
return i;
}
}
return -1;
}
void add(T val){
T* newAr;
if (nextIndex == length) {
length *=2;
newAr = new T[length];
for(int i = 0; i < nextIndex; i++){
newAr[i] = array[i];

}
delete[] array;
array = newAr;
}
array[nextIndex++] = val;
}
friend ostream& operator <<(ostream& out,DynArray<T>* obj) {
cout << "Values: ";
for (int i = 0; i< obj -> getNextIndex(); i++){
out << obj -> getIndex(i) << " ";
}
cout << endl;
return out;
}
};
#endif //CEF07B_DYNARRAY_H

Fisierul MultiMap.h
//
// Created by JACK on 11/17/2015.
//
#ifndef CEF07B_MULTIMAP_H
#define CEF07B_MULTIMAP_H
#include "DynArray.h"
template <typename K,typename V>
class MultiMap {
private:
DynArray<K>* key;
DynArray< DynArray<V>* >* value;
public:
MultiMap(){
value = new DynArray< DynArray<V>* >();
key = new DynArray<K>();
}
~MultiMap(){
delete(value);
delete(key);
}
void add(K key,V val) {
if (this -> key -> isIn(key)) {
value -> getIndex(this -> key -> indexofVal(key)) ->
add(val);
}
else {
this -> key -> add(key);
DynArray<V>* valArray = new DynArray<V>();
valArray -> add(val);
value -> add(valArray);
}
}
void removeByKey(K key){
value -> getIndex(this -> key -> indexofVal(key)) -> clear();
}
V getLength(K key1){
DynArray<V>* a = value -> getIndex(key -> indexofVal(key1));
V count = 0;
for (int i = 0; i < a -> getLength(); i++) {
if (a -> getIndex(i) >= 0) {

count++;
}
}
return count;
}
DynArray<V>* getByKey(K key){
return value -> getIndex(this -> key -> indexofVal(key));
}
DynArray<V>* operator[](K key) const {
return value -> getIndex(this -> key -> indexofVal(key));
}
friend ostream& operator <<(ostream& out,MultiMap<K,V>& obj) {
for(int i = 0; i < obj.key -> getLength(); i++) {
out << "Key: "<< obj.key -> getIndex(i) << endl;
out << obj.value -> getIndex(i);
out << endl;
}
return out;
}
};
#endif //CEF07B_MULTIMAP_H

Fisierul main.cpp
#include <iostream>
#include <stdlib.h>
#include "MultiMap.h"
using namespace std;
int main() {
MultiMap<string,int> myMultiMap;
myMultiMap.add("key1",5);
myMultiMap.add("key2",4);
myMultiMap.add("key2",7);
myMultiMap.add("key1",9);
cout << myMultiMap;
cout << "After removeByKey"<<endl;
myMultiMap.removeByKey("key1");
cout << myMultiMap;
cout<< "Lenghth of 'key2': "<< myMultiMap.getLength("key2") << endl;
cout<< "getByKey : ";
cout << myMultiMap.getByKey("key2");
cout << "operator [] : ";
cout << myMultiMap["key2"];
system("pause");
return 0;
}

Concluzie:
In urma efectuarii acestei lucrari de laborator capatat cunostinte despre
modul de lucru sabloanele in C++,in cazul functiilor parametrizate dupa
parerea mea este un mecanism foarte util si usor de interpretat,iar in cazul
claselor dupa parerea mea mecanismul de scriere este foarte complicat
trebuie de prevazul ca oriude sa fie genericul prezent.
Deasemnea un minus foarte mare a mecanismului dat este ca functionalul
functiilor clasei si declararea lor trebuie sa se afle in acelasi fisier,adica nu
poate fi structurat programul in fisier .h fisier sursa .cpp si main.cpp.