Constructori
si destructori
Initializarea datelor
La declararea datelor de tip predefinit sau definit de
utilizator prin structuri sau clase, compilatorul aloca o zona de memorie
corespunzatoare tipului respectiv. Este indicat ca în cazul în care datele
structurate au ca membrii pointeri, sa se aloce memorie în mod dinamic.
În general, datele numerice (globale) au valori
implicite; sunt initializate automat cu valoarea 0 iar cele de tip sir de
caractere cu sirul vid.. Initializarea datelor simple de tip predefinit se
poate realiza dupa declararea acestora, sau în momentul declararii.
Exemple:
int i; i=30;//declararea variabilei i, apoi initializarea ei prin
atribuire
char c='A'; //declararea si initializarea variabilei c
Initializarea datelor structurate se poate realiza în
momentul declararii acestora, prin listele de initializare.
Exemple:
//1
int a[]={20, 30, 40, 50}; //declararea si initializarea vectorului a
//2
double m[2][3]={{1.1,2.2,3.3}, {11.11,22.22,33.33}};//declararea si
initializarea matricii m
//3
struct pers{
char nume[20]; int varsta; double salariu;
}p={"Popescu", 20, 8000000};
·
Constructori
Constructorii sunt metode speciale care folosesc la crearea si initializarea
instantelor unei clase.
·
Programatorul
poate defini un constructor.
·
In absenta
altor definitii, clasei i se ataseaza in mod implicit un constructor. Un astfel
de constructor se numeste constructor implicit.
·
Constructorii
impliciti nu au parametri
·
Constructorii
impliciti nu se genereaza in cazul in care clasa are atasat un alt
constructor (asadar constructorii
impliciti sunt constructori fara parametri generati automat de limbaj daca
programatorul nu si-a definit unul).
·
Constructorii
au acelasi nume ca si clasa careia îi apartin
·
Constructorii
sunt apelati de fiecare data când se creaza noi instante ale clasei.
class complex
{public:
float x,y,m; //datele clasei
void display();//metodele clasei
float modul();};
float complex::modul()
{return sqrt(x*x+y*y);
}
void complex::display()
{cout<<x<<"+"<<y<<"*i";}
Clasa nu are definit un constructor prin urmare este generat in mod automat un constructor implicit care va permite declararea unor instante ale clasei astfel:
void main()
{ complex q1; //constructorul implicit permite instantiarea
clasei complex
complex *q=new complex;
cout<<q1.x<<”
„<<q1.y; //afiseaza valori reziduale
cout<<endl<<q->x<<” „<<q->y;
//afiseaza valori reziduale
……………..
}
Cum am mai spus, programatorul isi poate defini constructori proprii.
Constructorii vor fi definiti ca niste functii fara tip, fara a se trece in
dreptul constructorului cuvantul cheie void. Constructorul va avea acelasi nume
ca si al clasei careia ii apartine.
O clasa poate
avea mai multi constructori, care difera între ei prin numarul si tipul
parametrilor acestora. Acest lucru este posibil deoarece limbajul C++ permite
supradefinirea ( supraincarcarea=overloading) functiilor.
Supraîncarcarea (supradefinirea) reprezinta posibilitatea de a atribui unui nume mai multe semnificatii, care sunt selectate în functie de context. Practic, se pot defini functii cu acelasi nume, dar cu liste de parametri diferite, ca numar si/sau ca tipuri de parametri. În momentul apelului functiei, selectarea functiei adecvate se face în urma compararii tipurilor parametrilor efectivi cu tipurile parametrilor formali. De aceea, declararea unor functii cu acelasi nume si acelasi set de parametri este ilegala si este semnalata ca eroare la compilare.
La întâlnirea
declararii unui obiect, se apeleaza automat un constructor al clasei
respective. La fiecare instantiere a clasei se aloca memorie pentru datele
membre. Deci pentru fiecare obiect declarat se aloca memorie pentru datele
membre ale clasei. Functiile membru exista într-un singur exemplar pentru toate
instantele clasei.
Ordinea în care sunt apelati
constructorii corespunde ordinii declararii obiectelor.
Proprietatile constructorilor:
Exemple de costructori definiti de catre programator:
Ex1
#include<math.h>
#include<iostream.h>
#include<conio.h>
class complex
{public:
float x,y,m; //datele clasei
void display();
float modul(); //metoda clasei
complex() //constructor fara
parametri definit de catre programator
{cout<<endl<<"mesaj de la
constructor"<<endl;}
};
float complex::modul()
{return sqrt(x*x+y*y);
}
void complex::display()
{cout<<x<<"+"<<y<<"*i";}
complex q;
void main()
{complex q1,q2;
getch();
clrscr();
}
Testand programul anterior veti observa ca se
afiseaza pe ecran de trei ori mesajul: mesaj de la constructor, corespunzator fiecarei declarari a celor trei
instante ale clasei complex.
Urmatorul exemplu contine in plus inca un constructor definit de catre programator, constructor ce are un parametru.
Ex2
#include<math.h>
#include<iostream.h>
#include<conio.h>
class complex
{public:
float x,y,m; //datele clasei
void display();
float modul(); //metoda clasei
complex()
{cout<<endl<<"mesaj de la
constructor"<<endl;}
complex(float yy);
};
complex::complex(float
xx)
{x=xx;
y=0;
}
float complex::modul()
{return sqrt(x*x+y*y);
}
void complex::display()
{cout<<endl<<x<<"+"<<y<<"*i";
cout<<endl;
}
complex q;
void main()
{cout<<"Obiectul global q=";
q.display();
complex q1;
cout<<"Obiectul local q1, retine valori reziduale";
q1.display();
complex q2(6.7); //se apleleaza
constructorul cu un parametru
q2.display();
getch();
clrscr();
}
Urmatorul exemplu permite prin intermediul mecanismului de supraincarcare definirea unui constructor cu doi parametri:
Ex3
#include<math.h>
#include<iostream.h>
#include<conio.h>
class complex
{public:
float x,y,m; //datele clasei
void display();
float modul(); //metoda clasei
complex()
{cout<<endl<<"mesaj de la
constructor"<<endl;}
complex(float yy);
complex(float xx, float yy);
};
complex::complex(float xx)
{x=xx;
y=0;
}
complex::complex(float
xx, float yy)
{x=xx; y=yy;
}
float complex::modul()
{return sqrt(x*x+y*y);
}
void complex::display()
{cout<<endl<<x<<"+"<<y<<"*i";
cout<<endl;
}
complex q;
void main()
{cout<<"Obiectul global q=";
q.display();
complex q1;
cout<<"Obiectul local q1, retine valori reziduale";
q1.display();
complex q2(6.7);
cout<<"q2=";
q2.display();
complex q3(1.2,1.3);
cout<<"q3=";
q3.display();
getch();
clrscr();
}
Ca orice alta functie în limbajul C++, constructorii pot avea parametri impliciti , fiind numiti constructori cu parametri impliciti. Varianta constructorului cu parametri impliciti poate fi adoptata în toate cazurile în care constructorul nu necesita argumente. Daca toti parametrii unui constructor sunt impliciti, apelul constructorului are forma unei simple declaratii . Constructorii pot fi apelati si în mod explicit . În cazul în care dorim sa instantiem obiecte atât initializate, cât si neinitializate se poate folosi un constructor implicit vid, care se va apela la instantierea obiectelor neinitializate .
Exemplul 4: Pentru clasa complex s-a definit un constructor cu parametri impliciti; din acest motiv s-a putut face declaratia "complex q;"
// varianta constructor cu parametri impliciti
// permite declarare de instante de tip complex fara parametri, cu un parametru sau doi
//foarte flexibil
#include<math.h>
#include<iostream.h>
#include<conio.h>
class complex
{public:
float x,y,m; //datele clasei
void display();
float modul(); //metoda clasei
complex(float xx=0,
float yy=0)
{cout<<endl<<"mesaj de la constructorul cu parametri
impliciti "<<endl;
x=xx;
y=yy;
}
};
float complex::modul()
{return sqrt(x*x+y*y);
}
void complex::display()
{cout<<endl<<x<<"+"<<y<<"*i";
cout<<endl;
}
complex q; //obiect neinitializat ; apelul nu se face in
mod explicit
void main()
{cout<<"Obiectul global q=";
q.display();
complex q1; //obiect neinitializat ; apelul nu se face in
mod explicit
cout<<"Obiectul local q1 ";
q1.display();
complex q2(6.7); // obiect initializatt.
cout<<"q2=";
q2.display();
complex q3(1.2,1.3); // obiect
initializat.
cout<<"q3=";
q3.display();
complex q4=complex(); // constructorul este apelat în mod explicit.
q4.display();
getch();
clrscr();
}
La apelul explicit al constructorului: complex q4=complex() evaluarea
expresiei complex() conduce la:
- Crearea unui obiect temporar de tip complex (obiect cu o adresa
precisa, dar inaccesibil);
- Apelul constructorului pentru acest obiect temporar;
- Copierea acestui obiect temporar în q4.
Constructori de copiere
Daca programatorul nu defineste un constructor de copiere, compilatorul
genereaza un asemenea constructor, implicit.
Pentru o clasa, se poate defini un contructor de copiere, care sa permita
copierea obiectelor. Deoarece parametrii unui constructor nu pot fi de tipul
definit de clasa al carei membru este, ci o referinta la acesta, constructorul
de copiere pentru clasa nume_clasa,
are, de obicei, prototipul:
nume_clasa
(nume_clasa & ob);
Parametrul transmis prin referinta este obiectul a carui copiere se realizeaza
Exemplul 5:
#include<math.h>
#include<iostream.h>
#include<conio.h>
class complex
{public:
float x,y,m; //datele clasei
void display();
float modul(); //metoda clasei
complex(float xx=0, float yy=0)
{cout<<endl<<"mesaj de la constructorul cu parametri impliciti "<<endl;
x=xx;
y=yy;
}
complex(complex &ob)
//constructor de copiere
{
cout<<endl<<"operatie de copiere ";
x=ob.x;
y=ob.y;
}
};
float complex::modul()
{return sqrt(x*x+y*y);
}
void complex::display()
{cout<<endl<<x<<"+"<<y<<"*i";
cout<<endl;
}
void main()
{complex q1(1.2,1.3);
cout<<"q1=";
q1.display();
complex q2=q1; //se apeleaza constructorul de copiere
cout<<"q2=";
q2.display();
complex q3=complex(q1); //se apeleaza
constructorul de copiere
cout<<"q3=";
q3.display();
getch();
clrscr();
}
Destructori
Destructorii sunt metode ale claselor care actioneaza în
sens invers, complementar, fata de constructori. Constructorii sunt folositi
pentru alocarea memoriei, initializarea datelor membru sau alte operatii (cum
ar fi, incrementarea unui contor pentru instantele clasei). Constructorul este
apelat în momentul declararii obiectelor.
Destructorul elibereaza memoria alocata de constructori. Destructorul este
apelat automat, la iesirea din blocul în care este recunoscut acel obiect.
Proprietatile destructorilor
Exemplu 6:
#include<math.h>
#include<iostream.h>
#include<conio.h>
class complex
{public:
float x,y,m; //datele clasei
void display();
float modul(); //metoda clasei
complex(float xx=0, float yy=0)
{cout<<endl<<"mesaj de la constructorul cu parametri impliciti "<<endl;
x=xx;
y=yy;
}
complex(complex &ob)
{ cout<<endl<<"operatie de copiere ";
x=ob.x;
y=ob.y;
}
~complex ()
{cout<<endl<<"am apelat destructorul pentru"<<endl; //destructor
display();}
};
float complex::modul()
{return sqrt(x*x+y*y);
}
void complex::display()
{cout<<endl<<x<<"+"<<y<<"*i";
cout<<endl;
}
void main()
{complex q1(1.1,1.1);
cout<<"q1=";
q1.display();
complex q2(2.2,2.2);
cout<<"q2=";
q2.display();
complex q3(3.3,3.3);
cout<<"q3=";
q3.display();
// getch();
}
Exercitiu:
Sa se defineasca tipul punct, cu datele membre x si y,
reprezentând abscisa si ordonata unui punct. Operatiile care pot fi realizate
asupra obiectelor de tip punct, sunt: afisare (afiseaza coordonatele unui
punct), deplasare (deplaseaza un punct, noile coordonate ale punctului fiind
obtinute prin adunarea unor valori transmise ca parametri, la valorile
anterioare ale coordonatelor), abscisa (returneaza valoarea abscisei), ordonata
(returneaza valoarea ordonatei). Se vor implementa, deasemenea, constructor cu
parametri impliciti, constructor având ca parametri valorile abscisei si a
ordonatei, constructor de copiere si destructor.
Sa se defineasca tipul segment, cu datele membre A si B, de
tip punct, reprezentând capetele unui segment (originea si vârful). Operatiile
care pot fi realizate asupra obiectelor de tip segment, sunt: afisare (afiseaza
coordonatele capetellor segmentului), deplasare (translateaza un segment,
deplasând capetele acestuia cu valorile transmise ca parametri), origine
(returneaza originea segmentului), vârf (returneaza vârful segmentului). Se vor
implementa, deasemenea, constructor, constructor de copiere si destructor.
Sa se testeze tipurile de date punct si segment.
#include <iostream.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
//CLASA PUNCT
class punct
{ double x,y;
public:
punct()
{x=0;y=0;cout<<"Constr. implicit pentru
punct("<<x<<","<<y<<")\n";}
//constructor initializare
punct(double,double);
punct(punct&); //constructor copiere
~punct(); //destructor
double abscisa(){return x;}
double ordonata(){return y;}
void afisare();
void deplasare(double,double);
};
//CLASA SEGMENT
class segment
{private:
punct A,B;
public:
segment(punct&,punct&); //constructor
segment(segment&); //constructor copiere
~segment(); //destructor
punct origine();
punct varf();
void afisare();
void translatie(double,double);
};
//METODELE CLASEI PUNCT
punct::punct(double valx,double valy)
{ x=valx;y=valy; cout<<"Constructor punct
("<<x<<","<<y<<")\n"; }
punct::~punct()
{cout<<"Destructor punct
("<<x<<","<<y<<")\n";}
punct::punct( punct &P)
{ x=P.x;y=P.y; cout<<"Constructor copiere pct
("<<x<<","<<y<<")\n";}
void punct::deplasare(double dx,double dy)
{x+=dx; y+=dy;}
void punct::afisare()
{ cout<<"Punct ("<<x<<','<<y<<')';}
//METODELE CLASEI SEGMENT
segment::segment(punct &A1,punct &B1)
{ A=A1;B=B1;cout<<"Constructor segment[";A.afisare();B.afisare();
cout<<"]\n";}
segment::segment(segment &AB)
{ A=AB.A; B=AB.B; cout<<"Constructor copiere segment [";
A.afisare(); B.afisare();cout<<"]\n";}
punct segment::origine()
{ return A;}
punct segment::varf()
{ return B;}
void segment::afisare()
{ cout<<"[";A.afisare();cout<<',';
B.afisare();cout<<"]"<<'\n'; }
segment::~segment()
{ cout<<"Destructor segment [";A.afisare();
cout<<",";B.afisare();
cout<<"]\n";}
void segment::translatie(double dx,double dy)
{ A.deplasare(dx,dy); B.deplasare(dx,dy);}
void main()
{clrscr();
punct P(7.8,-20.4),Q(-4.82,8.897),A,B;
/*Constructor punct (7.8,-20.4) (Pentru punctul P)
Constructor punct (-4.82,8.897) (Pentru punctul Q)
Constr. implicit pentru punct(0,0)
Constr. implicit pentru punct(0,0) (pentru punctele A, B)*/
punct P3, Q3;
// Constr. implicit pentru punct(0,0)Constr. implicit pentru punct(0,0) (pentru
punctele P3, Q3)
segment S(P,Q);
/* Constr. implicit pentru punct(0,0)Constr. implicit pentru punct(0,0)
(pentru membrii A, B ai obiectului S, deci pentru S.A si S.B)
Constructor segment[Punct (7.8,-20.4)Punct (-4.82,8.897)] (pentru obiectul S,
de tip segment) */
segment S1(P3,Q3);
/* Constr. implicit pentru punct(0,0)
Constr. implicit pentru punct(0,0) (pentru membrii A, B ai obiectului S1, deci
pentru S1.A si S1.B)
Constructor segment[Punct (0,0)Punct (0,0)] (pentru obiectul S1, de tip
segment) */
printf("Apasa un car. ptr. continuare!\n"); getch();
cout<<"Punctele:\n";
P.afisare();cout<<'\n'; Q.afisare();cout<<'\n';
P3.afisare();cout<<'\n'; Q3.afisare();cout<<'\n';
A.afisare(); cout<<'\n'; B.afisare();cout<<'\n';
cout<<"\nSegment:"; S.afisare(); cout<<'\n';
/* Punctele:
Punct (7.8,-20.4) (pentru obiectul P)
Punct (-4.82,8.897) (pentru obiectul Q)
Punct (0,0) (pentru obiectul A)
Punct (0,0) (pentru obiectul B)
Punct (0,0) (pentru obiectul P3)
Punct (0,0) (pentru obiectul Q3)
Segment:[Punct (7.8,-20.4),Punct (-4.82,8.897)] */
punct D(1,2); punct C;
// Constructor punct (1,2)Constr. implicit pentru punct(0,0) (pentru punctele
D, C)
C=D; //operatie de atribuire
C.afisare(); // Punct (1,2) (pentru punctul C)
getch();
punct CC=C; // Constructor copiere pct (1,2)
cout<<"In urma copierii:"; CC.afisare();
// În urma copierii:Punct (1,2) (pentru punctul CC)
cout<<"Se deplaseaza punctul CC cu valorile 10, 20. Noile
coord.=";
CC.deplasare(10, 20); CC.afisare();
// Se deplaseaza punctul CC cu valorile 10, 20. Noile coord.=Punct (11,22)
cout<<"Abscisa CC="<<CC.abscisa()<<" Ordonata
CC="<<CC.ordonata()<<'\n';
//Abscisa CC=11 Ordonata CC=22
cout<<"Varf segment S="; (S.varf()).afisare();
// Varf segment S=Constructor copiere pct (-4.82,8.897) (metoda varf returneaza
un punct, copiere)
// Punct (-4.82, 8.897)
//Destructor punct (-4.82,8.897)
cout<<"Origine segment S="; CC=S.origine();
/* Origine segment S=Constructor copiere pct (7.8,-20.4) (metoda origine
returneaza un punct, copiere) Destructor punct (7.8,-20.4) */
CC.afisare(); // Punct (-4.82, 8.897)
S1=S; //operatie de atribuire
S1.afisare();
// Punct (7.8,-20.4)[Punct (7.8,-20.4),Punct (-4.82,8.897)]
cout<<"Translatie S1 cu 100,1000. S1 translatat este:";
S1.translatie(100, 1000); S1.afisare();
// Translatie S1 cu 100,1000. S1 translatat este:[Punct (107.8,979.6),Punct
(95.18,1008.897)]
segment S2=S1; /* Constr. implicit pentru punct(0,0) (pentru S2.A)
Constr. implicit pentru punct(0,0) (pentru S2.B)
Constructor copiere segment [Punct (107.8,979.6)Punct (95.18,1008.897)]
Destructor segment [Punct (107.8,979.6),Punct (95.18,1008.897)]*/
cout<<"Segment S2 obtinut prin copiere:";
S2.afisare(); // Segment S2 obtinut prin copiere:[Punct (107.8,979.6),Punct
(95.18,1008.897)]
cout<<"Iesire din main\n"; // Iesire din main
}
/* La iesirea din functia main, deci la terminarea duratei de viata a obiectelor,
se apeleaza automat destructorii, în ordinea inversa în care au fost apelati
constructorii, astfel:
Destructor segment [Punct (107.8,979.6),Punct (95.18,1008.897)] (pentru
segmentul S2)
Destructor punct (95.18,1008.897) (pentru membrii B, respectiv A, ai
segmentului S2: S2.B, apoi S2.A)
Destructor punct (107.8,979.6)
Destructor punct (7.8,-20.4) (pentru CC)
Destructor punct (1,2) (pentru C)
Destructor punct (1,2) (pentru D)
Destructor segment [Punct (107.8,979.6),Punct (95.18,1008.897)] (pentru
segmentul S1)
Destructor punct (95.18,1008.897) (pentru membrii B, respectiv A, ai
segmentului S1: S1.B, apoi S1.A)
Destructor punct (107.8,979.6)
Destructor segment [Punct (7.8,-20.4),Punct (-4.82,8.897)] (pentru segmentul S)
Destructor punct (-4.82,8.897) (pentru membrii B, respectiv A, ai segmentului
S: S.B, apoi S.A)
Destructor punct (7.8,-20.4)
Destructor punct (0,0) (pentru punctul Q3)
Destructor punct (0,0) (pentru punctul P3)
Destructor punct (0,0) (pentru punctul B)
Destructor punct (0,0) (pentru punctul A)
Destructor punct (-4.82,8.897) (pentru punctul Q)
Destructor punct (7.8,-20.4) (pentru punctul P) */
Exercitiul evidentiaza urmatoarele probleme:
1. În situatia în care o clasa C1 are ca date membre obiecte ale altei clase C2
(clasa segment are ca date membre obiecte de tipul punct), la construirea unui
obiect din C1, se apeleaza întâi constructorul C2 pentru membrii (de tip C2),
apoi constructorul C1.
Un astfel de exemplu îl constituie declararea segmentului S: segment
S(P,Q);
Se apeleaza întâi constructorul implicit al clasei punct pentru membrii A si B
ai segmentului S (deci pentru S.A si S.B), apoi constructorul clasei segment .
La distrugerea obiectului din clasa C1, destructorii sunt apelati în ordinea
inversa constructorilor (întâi se apeleaza destructorul clasei segment -
învelisul exterior, apoi destructorul pentru membrii de tip punct).
2. Sa revedem secventa:
punct D(1,2); punct C; C=D;
În acest caz, se realizeaza o atribuire, membru cu membru, echivalenta cu
C.x=D.x si C.y=D.y.
3. Sa revedem secventa:
punct CC=C;
În acest caz, se apeleaza constructorul de copiere, care creaza punctul CC prin
copierea punctului C. Apelul constructorului de copiere se poate realiza si
explicit:
punct CC=punct(C);
4. Parametrii transmisi unei functii pot fi obiecte, pointeri catre obiecte sau
referinte catre obiecte. Valoarea returnata de o functie poate fi un obiect,
pointer catre obiect sau referinta catre obiect.
segment::segment(punct &A1,punct &B1)
{ A=A1;B=B1;cout<<"Constructor segment\n";}
Constructorul primeste ca parametri referinte catre obiecte de tipul punct.
Apelul constructorului:
segment S(P, Q);
Parametrii efectivi P si Q sunt referinte pentru A1 si B1 (aceleasi obiecte).
Ca urmare, se apeleaza cei doi constructori impliciti pentru membrii A si B ai
segmentului S. În urma operatiei de atribuire din corpul constructorului
segmentului, ei sunt initializati. Mesajele:
"Constructor pct implicit!!" (pentru membrul A al segmentului S)
"Constructor pct implicit!!" (pentru membrul B al segmentului S)
"Constructor segment" (pentru segmentului S)
Constructorului puteau sa i se transmita parametri prin pointeri:
segment::segment(punct *A1,punct *B1)
{ A=*A1;B=*B1;cout<<"Constructor segment\n";}
Apelul: segment S(&P, &Q);
Parametrii formali A1 si B1 sunt initializati în momentul apelului
constructorului cu adresele punctelor P, respectiv Q. Situatia este similara
celei anterioare, mesajele obtinute sunt identice celor obtinute în cazul
transmiterii parametrilor prin referinta.
Constructorului puteau sa i se transmita parametri prin valoare:
segment::segment(punct A1,punct B1)
{ A=A1;B=B1;cout<<"Constructor segment\n";}
Apelul: segment S(P, Q);
În aceasta situatie, la apel, pentru parametrii formali A1 si B1 se rezerva
memorie pe stiva: obiectele locale constructorului, A1 si B1, sunt initializate
prin copiere (la transmiterea parametrilor prin valoare, se realizeaza o
copiere a parametrilor efectivi în parametrii formali). La terminarea executiei
corpului functiei, punctele A1 si B1 sunt distruse. De aceea, mesajele din
aceasta situatie, sunt:
"Constructor copiere punct!!" (pentru A1, local
constructorului)
"Constructor copiere punct!!" (pentru B1, local
constructorului)
"Constructor pct. implicit!!" (pentru membrul A al segmentului)
"Constructor pct. implicit!!" (pentru membrul B al segmentului)
"Constructor segment!" (pentru segmentul S)
"Destructor punct!" (pentru B1, la iesirea din constructor)
"Destructor punct!" (pentru A1, la iesirea din constructor)
Exercitiu: Pentru tipurile punct si segment implementate anterior, sa se scrie si sa se testeze urmatorul program, în care obiectele A, B (de tip punct) si AB (de tip segment) sunt globale (declarate în afara oricarei functii). Se folosesc, deasemenea, variabile locale statice. Pentru variabilele globale (A, B, AB) si cele locale declarate explicit statice (P1 din test1, U si V din blocul interior functiei main), se aloca memorie statica. Pentru variabilele locale se aloca memorie automatic, pe stiva. Sa se urmareasca evidentieze crearea si distrugerea obiectelor statice si automatici, domeniul de vizibilitate si timpul de viata.
class punct{ //. . . . .
};
class segment
{ //. . . . .
};
//Implementarea metodelor clasei punct
//Implementarea metodelor clasei segment
punct test1()
{ cout<<"Intrare in test1\n";
static punct P1(20,10);
P1.deplasare(1,1); cout<<"Iesire din test1\n";return P1;}
punct test2()
{ punct P1(100,100);P1.deplasare(10,20);return P1; }
punct A(1,2), B;
segment AB(A, B);
void main()
{cout<<"S-a intrat in main!\n"; punct E(1, 1), F, G;
F=test1(); cout<<"F="; F.afisare();
getch();G=test2();cout<<"Intrare in
test1\n";cout<<"G="; G.afisare();
{
cout<<"Intrare in blocul interior\n";
static punct U(5,2);punct C(9,9), D(5.5,6.6);static punct V(8,3);getch();
F=test1(); cout<<"Intrare in
test1\n";F.afisare();G=test2(); cout<<"Intrare in
test2\n";G.afisare();
cout<<"Iesire din blocul interior\n";
}
getch();A.afisare();F.afisare();AB.afisare();AB.translatie(10, 10);
cout<<"Segment translatat:"; AB.afisare();
cout<<"Segmentul AB are originea:"; (AB.origine()).afisare();
cout<<"Segmentul AB are varful:"; (AB.varf()).afisare();
cout<<"Iesire din main()\n";
}