4.3.Func?ii prietene

4.3.Func?ii prietene

Clasa fractie_rationala nu va fi de mare folos, dac? utilizatorul nu va avea posibilitatea de a efectua diferite calcule cu frac?ii ra?ionale. ?n primul r?nd se cer opera?ii de adunare, sc?dere, comparare la egalitate etc. Aceste opera?ii pot fi realizate prin func?ii separate, care nu sunt membre ale clasei. Orice func?ie de acest tip, av?nd la intrare dou? obiecte fractie_rationala, poate efectua calculele, acces?nd c?mpurile obiectelor prin intermediul func?iilor membre (cum ar fi numarator(), numitor(), modif()). ?ns?, uneori, ar fi de dorit ca func?ia ce efectueaz? calculele s? acceseze direct toate p?r?ile componente ale obiectelor parametri. Acest lucru poate fi f?cut folosind no?iunea de func?ie prieten? a clasei.

Func?ia separat? care nu este membr? a clasei, dar are acces deplin la to?i membrii clasei (inclusiv cei proteja?i ?i cei priva?i), se nume?te func?ie prieten? (engl. friend) a acestei clase. Pentru ca o func?ie s? fie prieten? a unei clase, trebuie de inclus prototipul acestei func?ii precedat de cuv?ntul-cheie friend ?n orice sec?iune din declara?ia clasei respective

Dezvolt?m exemplul cu clasa fractie_rationala mai departe. Anume: cre?m trei func?ii prietene ale acestei clase numitor_comun(), egale(), suma():

// Clasa fractie_rationala cu func?ii prietene
#include <stdlib.h>
#include <stdiostr.h>
 
class fractie_rationala
{
   protected:
      unsigned int numarat;
      unsigned int numit;
 
   public:
      fractie_rationala(unsigned int numarat_init=0,
                        unsigned int numit_init=1)
      {}
      void print(){}
      void modif(unsigned int numarat_nou=0,
                 unsigned int numit_nou=1) {}
      unsigned int numarator(){}
      unsigned int numitor(){}
 
      void reducere();
 
      friend void numitor_comun(fractie_rationala&,
                               fractie_rationala&);
      friend int egale(fractie_rationala x,
                       fractie_rationala y);
      friend fractie_rationala suma(fractie_rationala,
                                fractie_rationala);
   private:
      void eroare(char* mesaj) {}
};
 
void fractie_rationala::reducere()
{// codul precedent
}
 
void numitor_comun(fractie_rationala &x, fractie_rationala &y)
{
   if(x.numit!=y.numit)
   {
      x.numarat=x.numarat*y.numit;
      y.numarat=y.numarat*x.numit;
      x.numit=y.numit=x.numit*y.numit;
   }
}
 
int egale(fractie_rationala x, fractie_rationala y)
{
   numitor_comun(x, y);
   return x.numarat==y.numarat;
}
 
fractie_rationala suma(fractie_rationala x,
                       fractie_rationala y)
{
   fractie_rationala u;
   u.numarat=x.numarat*y.numit+x.numit*y.numarat;
   u.numit=x.numit*y.numit;
   u.reducere();
   return u;
}
 
void main()
{
   fractie_rationala fr1(1, 3);
   fractie_rationala fr2(2, 5);
 
   fr1.print();
   cout << " si ";
   fr2.print();
   cout << endl;
   numitor_comun(fr1, fr2);
   cout << "aduse la un numitor comun"
        << " au devenit respectiv\n";
   fr1.print();
   cout << " si ";
   fr2.print();
   cout << endl;
 
   fractie_rationala fr3(1, 2);
   fractie_rationala fr4(1, 4);
   fractie_rationala fr5(2, 4);
 
   fr3.print();
   cout << " si ";
   fr4.print();
   if(egale(fr3,fr4))
      cout << " sunt egale\n";
   else
      cout << " nu sunt egale\n";
 
   fr3.print();
   cout << " si ";
   fr5.print();
   if(egale(fr3,fr5))
      cout << " sunt egale\n";
   else
      cout << " nu sunt egale\n";
 
   fr3.print();
   cout << " + ";
   fr4.print();
   cout << " = ";
   suma(fr3,fr4).print();
   cout << endl;
 
   fr3.print();
   cout << " + ";
   fr4.print();
   cout << " + ";
   fr5.print();
   cout << " = ";
   suma(suma(fr3,fr4),fr5).print();
   cout << endl;
 
   char c; cin >> c; 
}

Func?ia numitor_comun(), av?nd la intrare dou? obiecte fractie_rationala, le aduce la un numitor comun. Atrage?i aten?ia c? obiectele se transmit prin referin??, fapt necesar, fiindc? ele ??i schimb? con?inuturile. ?n func?ia main() este ar?tat apelul func?iei numitor_comun() pentru dou? obiecte fr1 ?i fr2.

Func?ia egale() compar? dou? obiecte fractie_rationala la egalitate. Obiectele se transmit prin valoare. Func?ia ?ntoarce valoarea 1, dac? obiectele reprezint? dou? frac?ii egale, ?i ?ntoarce valoarea 0, dac? frac?iile sunt diferite. Obiectele se compar? dup? regulile pentru frac?ii, de aceea func?ia egale() mai ?nt?i aduce copiile primite ale obiectelor la un numitor comun ?i dup? aceasta compar? numitoarele. Modul de utilizare a func?iei egale() este ar?tat ?n func?ia main().

Func?ia suma() calculeaz? frac?ia ce reprezint? suma a dou? frac?ii-parametri. Atragem aten?ia cum o func?ie prieten? ?ntoarce ca rezultat un obiect fractie_rationala. Acest lucru ?l poate face ?i o func?ie membr? ?i o alt? func?ie arbitrar? (nemembr?). ?n func?ia main() se calculeaz? suma a dou? frac?ii fr3 ?i fr4. Deoarece rezultatul este un obiect fractie_rationala, putem aplica la el func?ia membr? print().

La rularea programului de mai sus va fi afi?at urm?torul rezultat:

1/3 si 2/5

aduse la un numitor comun au devenit respectiv

5/15 si 6/15

1/2 si 1/4 nu sunt egale

1/2 si 2/4 sunt egale

1/2 + 1/4 = 3/4

1/2 + 1/4 + 2/4 = 5/4

Cuv?ntul-cheie friend se scrie numai la prototipul func?iei ?n declararea clasei. El poate fi scris ?n orice loc ?nainte de numele func?iei (friend void sau void friend, nu conteaz?). Cuv?ntul-cheie friend nu poate fi scris la definirea func?iei.

Una ?i aceea?i func?ie poate fi prieten? pentru mai multe clase. Aceast? proprietate se folose?te ?n practic? destul de des. Astfel, func?ia prieten? simplific? accesarea datelor obiectelor de diferite tipuri.

O func?ie membr? a unei clase poate fi prieten? a altei clase sau a mai multor clase. Mai mult ca at?t, o clas? ?ntreag? poate fi prieten? a altei clase sau a mai multor clase. Astfel, fiecare func?ie membr? a clasei prieten? are acces direct la toate p?r?ile componente ale claselor respective.

Exerci?iul 4.2. De cercetat de sine st?t?tor ultimele dou? propriet??i utiliz?nd a?a-numit? declarare (sau referire) ulterioar?:

class C1;  // clasa C1 fa vi explicat? mai jos  
class C2   // aici putem referi clasa C1
{};
 class C1   // descrierea clasei C1, aici putem referi clasa C2 
{};


_________________________
Autorul: dr.conf. S. Pereteatcu

рассказать друзьям и получить подарок

Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Translate Переводчик

Подписка на новости

SmartResponder.ru
Ваш e-mail: *
Ваше имя: *

Хостинг для Wordpress сайтов