Documente Academic
Documente Profesional
Documente Cultură
Laborator V
Adrian Li / Ovidiu Grigore
2015
Scopul laboratorului
Desfurarea lucrrii
c l a s s Poligon
{
protected :
i n t nr_lat ;
double lungimi ;
public :
Poligon ()
{
c o u t << " P o l i g o n ( ) " << e n d l ;
t h i s >n r _ l a t = 0 ;
t h i s >l u n g i m i = NULL;
}
13
14
15
Poligon ( i n t nr_lat )
{
16
17
18
19
20
21
22
23
24
25
~Poligon ( )
{
c o u t << "~ P o l i g o n ( ) " << e n d l ;
i f ( t h i s >l u n g i m i != NULL)
d e l e t e [ ] t h i s >l u n g i m i ;
t h i s >l u n g i m i = NULL;
}
26
27
28
29
30
31
32
33
d o u b l e& o p e r a t o r [ ] ( i n t i n d e x )
{
d o u b l e aux ;
34
35
36
37
i f ( i n d e x < t h i s >n r _ l a t )
return lungimi [ index ] ;
else
{
c o u t << " Latura " << i n d e x << " nu e x i s t a ! " << e n d l ;
r e t u r n aux ;
}
38
39
40
41
42
43
44
45
46
d o u b l e perim ( )
{
c o u t << " P e r i m e t r u d i n P o l i g o n " << e n d l ;
47
48
49
50
double r e z u l t a t = 0 ;
f o r ( i n t i = 0 ; i < t h i s >n r _ l a t ; i ++)
r e z u l t a t += t h i s >l u n g i m i [ i ] ;
return rezultat ;
51
52
53
54
55
56
57
58
};
59
60
61
62
63
64
65
r e t u r n out ;
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
~Patrat ( )
{
c o u t << "~ P a t r a t ( ) " << e n d l ;
}
85
86
87
88
89
d o u b l e perim ( )
{
c o u t << " P e r i m e t r u d i n P a t r a t " << e n d l ;
90
91
92
93
r e t u r n 4 t h i s >l u n g i m i [ 0 ] ;
94
95
96
};
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
~Triunghi ( )
{
c o u t << "~ T r i u n g h i ( ) " << e n d l ;
}
113
114
115
116
117
118
bool este_dreptunghic ()
{
double l a t [ 3 ] ;
f o r ( i n t i = 0 ; i < 3 ; i ++)
l a t [ i ] = t h i s >l u n g i m i [ i ] ;
119
120
121
122
123
124
125
126
127
f o r ( i n t i = 0 ; i < 3 ; i ++)
f o r ( i n t j = i ; i < 3 ; i ++)
if ( lat [ j ] < lat [ i ])
{
d o u b l e aux = l a t [ j ] ;
lat [ j ] = lat [ i ] ;
l a t [ i ] = aux ;
}
128
129
if
( ( l a t [ 0 ] l a t [ 0 ] ) == ( l a t [ 1 ] l a t [ 1 ] ) + ( l a t [ 2 ] l a t [ 2 ] ) )
return true ;
else
return f a l s e ;
130
131
132
133
134
};
2.1
Polimorfism
P o l i g o n A = new P o l i g o n ( 5 ) ;
f o r ( i n t i = 0 ; i < 5 ; i ++)
( A) [ i ] = 1 0 ;
c o u t << A << e n d l ;
c o u t << A << e n d l ;
c o u t << A>perim ( ) << e n d l ;
d e l e t e A;
8
9
10
11
P a t r a t B = new P a t r a t ( 3 ) ;
c o u t << B>perim ( ) << e n d l ;
d e l e t e B;
12
13
14
15
16
T r i u n g h i C = new T r i u n g h i ( 3 , 4 , 5 ) ;
c o u t << C>perim ( ) << e n d l ;
c o u t << " T r i u n g h i u l e s t e d r e p t u n g h i c ? " << C>e s t e _ d r e p t u n g h i c ( )
<< e n d l ;
d e l e t e C;
Poligon ( i n t nr_lat )
004A6F68
P o l i g o n cu 5 l a t u r i de l u n g i m i : 10 10 10 10 10
Perimetru din Poligon
50
~Poligon ( )
7
8
9
10
11
12
Poligon ( i n t nr_lat )
Perimetru din Patrat
12
~Patrat ( )
~Poligon ( )
13
14
15
16
17
18
19
20
Poligon ( i n t nr_lat )
Triunghi (a , b , c )
Perimetru din Poligon
12
Triunghiul este dreptunghic ? 1
~Triunghi ( )
~Poligon ( )
P o l i g o n B = new P a t r a t ( 3 ) ;
c o u t << B>perim ( ) << e n d l ;
d e l e t e B;
Poligon ( i n t nr_lat )
Perimetru din Poligon
12
~Poligon ( )
Primele dou linii din consol sunt rezultatul primei linii de cod: se creaz
obiectul. Partea cu adevrat interesant se gsete la linia 2 din cod: rulm
funcia perim(), funcie care este implementat ntr-un fel n clasa Poligon
i altfel n clasa Patrat. Din consol (liniile 2 i 3) putem trage concluzia
c funcia rulat a fost cea din clasa de baz. Acest lucru se ntmpl din
urmtoarea cauz:
1. Pointerul B este un pointer la Poligon.
5
2.2
Funcii virtuale
Transformarea unei funcii din clasa de baz ntr-o funcie virtual spune compilatorului s caute funcia i n clasa derivat. Dac funcia este gsit n clasa
derivat, atunci o apeleaz. Dac funcia nu este redefinit n clasa derivat, o
va folosi pe cea din clasa de baz. Pentru a transforma o funcie ntr-o funcie
virtual se adaug n faa acesteia cuvntul cheie virtual.
1
2
3
4
5
6
7
8
9
10
11
12
c l a s s Poligon
{
protected :
i n t nr_lat ;
double lungimi ;
public :
Poligon ()
{
c o u t << " P o l i g o n ( ) " << e n d l ;
t h i s >n r _ l a t = 0 ;
t h i s >l u n g i m i = NULL;
}
13
14
15
16
17
18
19
20
21
22
23
24
Poligon ( i n t nr_lat )
{
c o u t << " P o l i g o n ( i n t n r _ l a t ) " << e n d l ;
t h i s >n r _ l a t = n r _ l a t ;
t h i s >l u n g i m i = new d o u b l e [ n r _ l a t ] ;
i f ( t h i s >l u n g i m i == NULL)
{
c o u t << " E r o a r e l a a l o c a r e " << e n d l ;
exit (0) ;
}
}
25
26
27
28
29
30
31
~Poligon ( )
{
c o u t << "~ P o l i g o n ( ) " << e n d l ;
i f ( t h i s >l u n g i m i != NULL)
d e l e t e [ ] t h i s >l u n g i m i ;
t h i s >l u n g i m i = NULL;
32
33
d o u b l e& o p e r a t o r [ ] ( i n t i n d e x )
{
d o u b l e aux ;
34
35
36
37
i f ( i n d e x < t h i s >n r _ l a t )
return lungimi [ index ] ;
else
{
c o u t << " Latura " << i n d e x << " nu e x i s t a ! " << e n d l ;
r e t u r n aux ;
}
38
39
40
41
42
43
44
45
46
v i r t u a l d o u b l e perim ( )
{
c o u t << " P e r i m e t r u d i n P o l i g o n " << e n d l ;
47
48
49
50
double r e z u l t a t = 0 ;
f o r ( i n t i = 0 ; i < t h i s >n r _ l a t ; i ++)
r e z u l t a t += t h i s >l u n g i m i [ i ] ;
return rezultat ;
51
52
53
54
55
56
57
58
};
59
60
61
62
63
64
65
r e t u r n out ;
66
67
P o l i g o n B = new P a t r a t ( 3 ) ;
c o u t << B>perim ( ) << e n d l ;
d e l e t e B;
Poligon ( i n t nr_lat )
Perimetru din Patrat
12
~Poligon ( )
P o l i g o n B = new T r i u n g h i ( 3 , 4 , 5 ) ;
c o u t << B>perim ( ) << e n d l ;
d e l e t e B;
2.3
Destructorul virtual
Transformarea destructorului n destructor virtual face posibil apelarea destructorului unui obiect prin pointerul clasei de baz. Acest lucru este foarte
util, prevenind programarea defectuas ce nu dezaloc memoria utilizat. Totui, dac la o funcie normal virtualizarea acesteia fcea compilatorul s execute doar funcia din clasa derivat, virtualizarea destructorului permite rularea
tuturor destructorilor, n ordine logic (de la cel mai derivat pn la cel de baz).
Not. n general, cnd lucrm cu clase derivate este bine ca destructorul s
fie, pe ct posibil, ntotdeauna virtual pentru fiecare clas implementat (chiar
dac este de baz sau derivat).
8
2.4
Pentru a putea nelege necesitatea funciilor pur virtuale, considerm urmtorul exemplu: clasei Poligon vrem s-i implementm o funcie care calculeaz
aria poligonului respectiv, n acelai mod cum funcia perim() poate calcula
perimetrul oricrui poligon posibil. Acest lucru este foarte greu, chiar imposibil
deoarece nu exist o formul general. Din acest motiv, pentru a ne asigura c
fiecrei clase derivate i se va implementa funcia double arie(), vom declara
n clasa de baz funcia arie ca fiind funcie pur virtual:
1
2
3
4
5
6
7
8
9
10
11
c l a s s Poligon
{
protected :
i n t nr_lat ;
double lungimi ;
public :
Poligon ()
{
t h i s >n r _ l a t = 0 ;
t h i s >l u n g i m i = NULL;
}
12
13
14
15
16
17
18
19
20
21
22
Poligon ( i n t nr_lat )
{
t h i s >n r _ l a t = n r _ l a t ;
t h i s >l u n g i m i = new d o u b l e [ n r _ l a t ] ;
i f ( t h i s >l u n g i m i == NULL)
{
c o u t << " E r o a r e l a a l o c a r e " << e n d l ;
exit (0) ;
}
}
23
24
25
26
27
28
29
v i r t u a l ~Poligon ( )
{
i f ( t h i s >l u n g i m i != NULL)
d e l e t e [ ] t h i s >l u n g i m i ;
t h i s >l u n g i m i = NULL;
}
30
31
32
33
d o u b l e& o p e r a t o r [ ] ( i n t i n d e x )
{
d o u b l e aux ;
34
i f ( i n d e x < t h i s >n r _ l a t )
return lungimi [ index ] ;
else
{
c o u t << " Latura " << i n d e x << " nu e x i s t a ! " << e n d l ;
r e t u r n aux ;
}
35
36
37
38
39
40
41
42
43
44
45
46
d o u b l e perim ( )
{
double r e z u l t a t = 0 ;
47
48
49
50
51
v i r t u a l double a r i a ( ) = 0 ;
52
53
54
55
};
56
57
58
59
60
61
62
r e t u r n out ;
63
64
#i n c l u d e <i o s t r e a m >
#i n c l u d e <math . h>
u s i n g namespace s t d ;
4
5
6
7
8
9
10
11
12
13
14
15
c l a s s Poligon
{
protected :
i n t nr_lat ;
double lungimi ;
public :
Poligon ()
{
t h i s >n r _ l a t = 0 ;
t h i s >l u n g i m i = NULL;
}
16
17
18
Poligon ( i n t nr_lat )
{
10
t h i s >n r _ l a t = n r _ l a t ;
t h i s >l u n g i m i = new d o u b l e [ n r _ l a t ] ;
i f ( t h i s >l u n g i m i == NULL)
{
c o u t << " E r o a r e l a a l o c a r e " << e n d l ;
exit (0) ;
}
19
20
21
22
23
24
25
26
27
v i r t u a l ~Poligon ( )
{
i f ( t h i s >l u n g i m i != NULL)
d e l e t e [ ] t h i s >l u n g i m i ;
t h i s >l u n g i m i = NULL;
}
28
29
30
31
32
33
34
d o u b l e& o p e r a t o r [ ] ( i n t i n d e x )
{
d o u b l e aux ;
35
36
37
38
i f ( i n d e x < t h i s >n r _ l a t )
return lungimi [ index ] ;
else
{
c o u t << " Latura " << i n d e x << " nu e x i s t a ! " << e n d l ;
r e t u r n aux ;
}
39
40
41
42
43
44
45
46
47
d o u b l e perim ( )
{
double r e z u l t a t = 0 ;
f o r ( i n t i = 0 ; i < t h i s >n r _ l a t ; i ++)
r e z u l t a t += t h i s >l u n g i m i [ i ] ;
return rezultat ;
}
48
49
50
51
52
53
54
55
v i r t u a l double a r i a ( ) = 0 ;
56
57
58
59
};
60
61
62
63
64
65
66
r e t u r n out ;
67
68
69
70
71
72
73
74
75
11
f o r ( i n t i = 0 ; i < 4 ; i ++)
t h i s >l u n g i m i [ i ] = 0 ;
76
77
78
79
80
81
82
83
84
85
~Patrat ( )
{
86
87
88
89
90
double a r i a ( )
{
r e t u r n ( t h i s >l u n g i m i [ 0 ] t h i s >l u n g i m i [ 0 ] ) ;
}
91
92
93
94
95
};
96
97
98
99
100
101
102
103
104
105
106
107
108
~Triunghi ( )
{
109
110
111
112
113
114
115
116
bool este_dreptunghic ()
{
double l a t [ 3 ] ;
f o r ( i n t i = 0 ; i < 3 ; i ++)
l a t [ i ] = t h i s >l u n g i m i [ i ] ;
117
f o r ( i n t i = 0 ; i < 3 ; i ++)
f o r ( i n t j = i ; i < 3 ; i ++)
if ( lat [ j ] < lat [ i ])
{
d o u b l e aux = l a t [ j ] ;
lat [ j ] = lat [ i ] ;
l a t [ i ] = aux ;
}
118
119
120
121
122
123
124
125
126
( ( l a t [ 0 ] l a t [ 0 ] ) == ( l a t [ 1 ] l a t [ 1 ] ) + ( l a t [ 2 ] l a t [ 2 ] ) )
return true ;
else
return f a l s e ;
if
127
128
129
130
131
132
12
double a r i a ( )
{
d o u b l e p = perim ( ) / 2 ;
r e t u r n s q r t ( p ( p t h i s >l u n g i m i [ 0 ] ) ( p t h i s >l u n g i m i [ 1 ] ) ( p
t h i s >l u n g i m i [ 2 ] ) ) ;
}
133
134
135
136
137
138
};
139
140
141
142
v o i d program ( )
{
P o l i g o n B = new P a t r a t ( 3 ) ;
143
c o u t << B << e n d l ;
c o u t << " Perim : " << B>perim ( ) << e n d l ;
c o u t << " A r i a : " << B>a r i a ( ) << e n d l ;
d e l e t e B;
144
145
146
147
148
T r i u n g h i T( 3 , 4 , 5 ) ;
c o u t << T << e n d l ;
c o u t << " Perim : " << T . perim ( ) << e n d l ;
c o u t << " A r i a : " << T . a r i a ( ) << e n d l ;
c o u t << " D r e p t u n g h i c ? " << T . e s t e _ d r e p t u n g h i c ( ) << e n d l ;
149
150
151
152
153
154
155
156
157
158
i n t main ( )
{
program ( ) ;
159
160
161
162
2.5
Interfee
Probleme
1. Pentru clasele din capitolul 2, creai un pointer la Poligon, i alocai dinamic un obiect de tip Triunghi. Folosind de funcia este_dreptunghic a
clasei Triunghi afiai dac trigunghiul respectiv este sau nu dreptunghic.
13