Sunteți pe pagina 1din 9

Ministerul Educaiei al Republicii Moldova

Universitatea Tehnic a Moldovei


Catedra Automatica si Tehnologii Informationale

RAPORT
Lucrarea de laborator nr.6
Tema: Polimorfism. Funcii virtuale
Varianta 10

A efectuat:
st. gr. SI-141

E. Cucu

A verificat:
Lector universitar

M. Balan

Chiinu 2015

Scopul lucrrii:
Studierea polimorfismului;
Studierea principiilor legturii trzii;
Studierea funciilor virtuale;
Polimorfismul ad-hoc;
Realizarea funciilor virtuale;
Studierea claselor abstracte.

Indicatii teoretice:
Cuvntul polimorfism provine i aproximativ se traduce ca multe forme (poly
multe, morphos - form). Cuvntul morphos are legtur cu zeul grec Morphus, care putea
s apar n vis oamenilor n oriice form n care el dorete.
n via tipurile polimorfe sunt acelea, care se caracterizeaz dup o cantitate de
diferite forme i caracteristici. n chimie legturile polimorfe se pot cristaliza, cel puin n
dou forme diferite (de exemplu, carbonul are dou forme cristaline grafitul i diamantul).
Din alt punct de vedere, inginerul TI este n primul rnd om, dar apoi este inginer (principiul
de substituire).
n limbajele de programare un obiect polimorf este esena (variabil, argumentul
funciei), care pstreaz, n timpul executrii programului valorile diferitor tipuri. Funciile
polimorfe sunt acele funcii, care au argumente polimorfe.
n ++ polimorfismul este o urmrile obinuit:
Relaia "a fi exemplar";
Mecanismul de expediere a mesajelor;
Motenirea;
Principiul de substituire.
Unul din posibilitile principale a utilizrii programrii orientate pe obiecte, const n
posibilitatea de a combina aceste medii. n rezultat se primete un set bogat de exemple
tehnice mpreun cu utilizarea repetat a codului.
Variabila polimorf: conine valoarea, care se refer la diferite tipuri de date.
Variabilele polimorfe realizeaz principiul de substituire. Cu alte cuvinte, cu toate c pentru
asemenea variabile exist un tip de date ateptat, tipul real poate fi un subtip a tipului ateptat.
n C++ variabilele polimorfe exist numai ca referine i pointeri.
Funciile polimorfe este una din cele mai puternice tehnici de programare obiect
orientate. Ele permit concomitent s scrii cod la un nivel nalt de abstractizare i apoi sa-l
utilizezi ntr-o situaie concret. De obicei programatorul execut ajustarea codului cu
ajutorul transmiterii mesajelor adugtoare destinatarului, care utilizeaz metoda. Aceste
metode adugtoare, deseori nu sunt legate cu clasa la nivelul abstractizrii metodei
polimorfe. Ele sunt metode virtuale, care se definesc pentru clasele de nivel mult mai jos.
Cnd unei adevrate variabile (adic nu unei referine i nu a pointerilor) i se atribuie
o valoare de tipul subclasa, atunci valoarea clasei dinamice se transmite obligatoriu aa,
pentru a coincide cu tipul static al variabilelor.
Totui la utilizarea referinelor sau a pointerilor valoarea salveaz tipul su dinamic.

Legturi trzii
Sub legturi trzii trebuie de neles mecanismul care permite definirea tipului
dinamic n timpul executrii programului, dar nu n timpul compilrii. Un mecanism
asemntor sunt descriptorii de fiiere, aa cum fiierele se deschid n timpul executrii
programului, dar nu n timpul compilrii. Acest mecanism este baza polimorfismului, aa
cum realizeaz funciile virtuale.
Funciile virtuale
Legturile trzii rezolv problema, dar, ea nu are cunotine nemijlocite n limbaj. De
aceia, pentru referire el este necesar de utilizat funciile virtuale, care se scriu cu utilizarea
cuvntului rezervat virtual. Funciile virtuale se deosebesc de cele obinuite numai prin
metodele de acces. Dar utilizarea lor are sens numai cu utilizarea referinelor sau a
pointerilor.
Aducem un exemplu:
#include<iostream.h>
class Animal{
public:
void Say(){ cout<<"!!!\n";}
};
class Dog: public Animal{
public:
void Say(){ cout<<"GAV\n";}
};
class Cat: public Animal{
public:
void Say(){ cout<<"MIAU\n";}
};
void FunSay(Animal a){
a.Say();
}
void main(){
Animal a;
Dog
d;
Cat
c;
FunSay(a);
FunSay(d);
FunSay(c);
}

n acest exemplu funciile globale nu sunt polimorfe, aa cum variabilele se transmit


dup valoare, ceia ce duce la pierderea caracteristicilor specifice a clasei derivate, mai mult
ca att, funcia Say nu este virtual. Deci, pentru funcionarea corect a acestei programe
sunt necesare urmtoarele modificri: funcia Say trebuie s fie definit ca virtual, dar
parametrul funciei globale trebuie s fie definit ca o referin sau un pointer.
Polimorfismul ad-hoc
Aspectul ce duce la confuzie de precizare a metodelor n limbajelor C++ este diferena
dintre predefinirea metodelor virtuale i nevirtuale.

Mai multe confuzii apar, dac programatorul ncearc s predefineasc funcia virtual
n subclas, dar cu aceasta el se refer (posibil, din greeal) alt tip de argumente. De
exemplu, clasa printe conine descrierea:
virtual void display (char *, int);

Subclasa ncearc s predefineasc metoda:


virtual void display (char *, short);

Aa cum listele de argumente se deosebesc, atunci a doilea definire nu se recunoate


ca o predefinire, dar ca suprancrcare. De aceea, de exemplu, la apelarea n forma tipului
printelui se va alege prima metod, darn u a doua. Aa erori sunt greu de gsit, deoarece
ambele forme de scriere sunt premise, i s speri la o diagnoz de compilator nu trebuie.
Civa autori prefer s considere suprancrcarea, i abloanele polimorfismului, aa
cum des se ntlnesc cu definirea mai multor forme. Totui trebuie de amintit, c
polimorfismul se realizeaz cu legturi trzii, n acel timp cnd problemele care apar la
utilizarea suprancrcrii i a abloanelor ce se rezolv la compilare. De aceia aceste
construcii a limbajului uneori se numesc polimorfismul ad-hoc.
Clasele abstracte
Metodele de amnare (cteodat se numesc metode abstracte, dar n C++ metode
virtuale) pot fi privite ca generalizarea predefinirii. n ambele cazuri comportamentul clasei
printe se modific pentru motenitor. Pentru metodele amnate, totui, comportamentul pur
i simplu nu este definit. Orice activitate folositoare este dat n clasa fiic.
class Shape {
public:
...
virtual void draw() = 0;
...
};

Compilatorul nu permite utilizatorului crearea unui exemplar a clasei, care conine pur
metodele virtuale, de aceia aceste clase sunt numite abstracte. Subclasele trebuie s
redefineasc aceste metode. Redefinirea numai a metodelor virtuale trebuie s derive din
descrierea ei n urmai, pentru care sunt create obiecte reale.

Sarcina lucrarii:
Creai clasa abstract de baz Instituie de nvmnt cu funcia virtual - descriere. Creai
clasele derivate instituie de nvmnt precolar, instituie de nvmnt medie i
instituie de nvmnt superioar n care funcia dat este predefinit. n funcia main
determinai masivul de pointeri la clasa abstract, crora li se atribuie adresele diferitor
obiecte.

Listingul programului:
Clasa abstracta Institutuion,clase derivate Preschool,Average,Higher.
Headeruri-le Institution,Preschool,Average,Higher.h
//
// Created by JACK on 11/9/2015.
//
#ifndef CEF06_INSTITUTION_H
#define CEF06_INSTITUTION_H
#include <iostream>
using namespace std;
class Institution {
string size;
public:
Institution(const string& size = "MEDIUM");
Institution& operator=(const Institution&);
virtual ~Institution();
virtual void get_description() const = 0;
};
#endif //CEF06_INSTITUTION_H
//
// Created by JACK on 11/9/2015.
//
#ifndef CEF06_PRESCHOOL_H
#define CEF06_PRESCHOOL_H
#include "Institution.h"
class Preschool : public Institution {
string name;
int graduate;
string location;
public:
Preschool();
Preschool(string,int,string);
Preschool& operator=(const Preschool&);
~Preschool();
virtual void get_description() const override;
};
#endif //CEF06_PRESCHOOL_H
//
// Created by JACK on 11/9/2015.
//
#ifndef CEF06_AVERAGE_H
#define CEF06_AVERAGE_H
#include "Institution.h"
class Average : public Institution {
string name;

int graduate;
string location;
public:
Average();
Average(string,int,string);
Average& operator=(const Average&);
~Average();
virtual void get_description() const override;
};
#endif //CEF06_AVERAGE_H
//
// Created by JACK on 11/9/2015.
//
#ifndef CEF06_HIGHER_H
#define CEF06_HIGHER_H
#include "Institution.h"
class Higher :public Institution {
string name;
int graduate;
string location;
public:
Higher();
Higher(string,int,string);
Higher& operator=(const Higher&);
~Higher();
virtual void get_description() const override;
};
#endif //CEF06_HIGHER_H

Fisierile sursa Institution,Preschool,Average,Higher.cpp


//
// Created by JACK on 11/9/2015.
//
#include "Institution.h"
Institution::Institution(const string& size):
size(size) { }
Institution& Institution::operator=(const Institution& obj) {
if(this == &obj) {
return *this;
}
size = obj.size;
return *this;
}
Institution::~Institution() {
size = "";
}
//

// Created by JACK on 11/9/2015.


//
#include "Preschool.h"
Preschool::Preschool():
name(""),graduate(0),location(){ }
Preschool::Preschool(string name,int capacity,string location):
name(name),graduate(capacity),location(location){ }
Preschool& Preschool::operator=(const Preschool& obj) {
if (this == &obj) {
return *this;
}
name = obj.name;
graduate = obj. graduate;
location = obj.location;
return *this;
}
Preschool::~Preschool() {
name = "";
graduate = 0;
location = "";
}
void Preschool::get_description() const {
cout << "\nType of Institution : PRESCHOOL\n";
cout << "Name of Institution : " << name;
cout << "\nGraduate : " << graduate;
cout << "\nLocation of instituion : " << location;
}
//
// Created by JACK on 11/9/2015.
//
#include "Average.h"
Average::Average():
name(""),graduate(0),location(location){ }
Average::Average(string name,int capacity,string location):
name(name),graduate(capacity),location(location){ }
Average& Average::operator=(const Average& obj) {
if (this == &obj) {
return *this;
}
name = obj. name;
graduate = obj. graduate;
location = obj.location;
return *this;
}
Average::~Average() {
name = "";
graduate = 0;
location = "";
}
void Average::get_description() const {

cout
cout
cout
cout

<<
<<
<<
<<

"\nType of Institution : AVERAGE\n";


"Name of Institution : " << name;
"\nGraduate : " << graduate;
"\nLocation of instituion : " << location;

}
//
// Created by JACK on 11/9/2015.
//
#include "Higher.h"
Higher::Higher():
name(""),graduate(0),location(location){ }
Higher::Higher(string name,int graduate,string location):
name(name),graduate(graduate),location(location){ }
Higher& Higher::operator=(const Higher& obj) {
if (this == &obj) {
return *this;
}
name = obj. name;
graduate = obj. graduate;
location = obj.location;
return *this;
}
Higher::~Higher() {
name = "";
graduate = 0;
location = "";
}
void Higher::get_description() const {
cout << "\nType of Institution : HIGHER\n";
cout << "Name of Institution : " << name;
cout << "\nGraduate : " << graduate;
cout << "\nLocation of instituion : " << location;
}

Fisierul main.cpp
#include <iostream>
#include <stdlib.h>
#include "Preschool.h"
#include "Average.h"
#include "Higher.h"
using namespace std;
int main() {
Institution* obj[3];
obj[0] = new Preschool("L.T M.Eminescu",4,"Ungheni");
obj[1] = new Average("M.Basarab",9,"Chisinau");
obj[2] = new Higher("V.Alecsandri",12,"Chisinau");
for (int i = 0; i < 3; i++) {
obj[i] -> get_description();
cout << endl;
}
for (int j = 0; j < 3; j++) {
delete obj[j];

}
system("pause");
return 0;
}

Concluzie:
In urma efectuarii acestei lucrari de laborator capatat cunostinte cu ultimul
mecanism OOP polimorfismul.
Este un mecanism foarte util din considerentul ca putem avea o clasa
abstracta care sa fie de fiecare data diferita,si sa foloseasca aceeasi functie
pentru diferite obiecte insa cu functional diferit.

S-ar putea să vă placă și