7.7. Suprascrierea ?i supra?nc?rcarea operatorilor ?n clasa derivat?

7.7. Suprascrierea ?i supra?nc?rcarea operatorilor ?n clasa derivat?

La fel ca ?i func?iile membre, operatorii supra?nc?rca?i ?n clasa de baz? pot fi suprascri?i ?i/sau supra?nc?rca?i ?i ?n clasa derivat?, folosind acelea?i reguli care au fost utilizate ?i la suprascrierea ?i la supra?nc?rcarea func?iilor mo?tenite. ?n plus, ?n clasa derivat? se mai pot supra?nc?rca operatori noi, cei care nu au fost supra?nc?rca?i ?n clasa de baz?. Folosind operatorul ::, ?n func?ia care suprascrie sau supra?ncarc? ?n clasa derivat? un operator mo?tenit de la clasa de baz? poate fi apelat? func?ia ce supra?ncarc? acest operator ?n clasa de baz? (bine?n?eles, dac? ultima func?ie nu este privat? ?n clasa de baz?).

Cercet?m operatorii supra?nc?rca?i ?n clasa de baz? fractie_rationala, analiz?nd pentru fiecare din ei necesitatea de a fi suprascri?i sau supra?nc?rca?i mai ?nt?i ?n clasa rational_fara_semn ?i apoi ?n clasa rational (suprascrierea ?i supra?nc?rcarea operatorilor pentru ultima clas? o ve?i face de sine st?t?tor ca exerci?iu).

Operatorul == trebuie s? fie numaidec?t suprascris, altfel vom avea, de exemplu, c? 1,1/2 va fi egal cu 1/2, ?i nu va fi egal cu 3/2. ?n clasa rational_fara_semn trebuie de prev?zut trei versiuni care supra?nc?rc? operatorul ==, pentru cazurile:

“rational_fara_semn == rational_fara_semn” (suprascrierea),

“rational_fara_semn == fractie_rationala” (supra?nc?rcarea) ?i

“fractie_rationala == rational_fara_semn” (supra?nc?rcarea).

Ultimul caz nu poate fi supra?nc?rcat prin func?ie membr?, ci doar printr-o func?ie prieten?. Deci, inser?m ?n sec?iunea public a clasei rational_fara_semn urm?torul cod:

iint rational_fara_semn::operator ==(rational_fara_semn y)
{
   fractie_rationala 
                x1( part_int*numit+numarat, numit),
                y1(y.part_int*y.numit+y.numarat, y.numit);
   return x1==y1;
}
 
int rational_fara_semn::operator ==(fractie_rationala y)
{
   fractie_rationala x1(part_int*numit+numarat, numit);
   return x1==y;
}
 
friend int operator ==(fractie_rationala x,
                       rational_fara_semn y)
{
   fractie_rationala y1(y.part_int*y.numit+y.numarat,y.numit);
   return x==y1;
}

Pentru verificare, la func?ia main(), ?n continuarea exemplului precedent, ad?ug?m urm?torul cod:

if(rational_fara_semn(1,1,2) == rational_fara_semn(1,2,4))
      cout << "1,1/2 si 1,2/4 sunt egale" << endl;
else
      cout << "1,1/2 si 1,2/4 nu sunt egale"<<endl;
 
if(rational_fara_semn(1,1,2) == fractie_rationala(1,2))
      cout << "1,1/2 si 1/2 sunt egale" << endl;
else
      cout << "1,1/2 si 1/2 nu sunt egale" << endl;
 
if(fractie_rationala(3,2) == rational_fara_semn(1,1,2))
      cout << "3/2 si 1,1/2 sunt egale" << endl;
else
      cout << "3/2 si 1,1/2 nu sunt egale" << endl;

care va afi?a urm?toarea ie?ire:

1,1/2 si 1,2/4 sunt egale

1,1/2 si 1/2 nu sunt egale

3/2 si 1,1/2 sunt egale

Exerci?iul 7.6. Suprascrie?i ?i supra?nc?rca?i operatorul == ?n clasa rational. Verifica?i lucrul operatorului supra?nc?rcat pentru diferite combina?ii ale argumentelor.

Suprascriem operatorul de atribuire = ?n clasa derivat? pentru ob?inerea valorii de la un obiect de aceea?i clas? derivat? ?i supra?nc?rc?m acest operator pentru ob?inerea valorii de la un obiect al clasei de baz?. ?n ambele cazuri obiectul destina?ie va fi supus reducerii ?i, ca rezultat, va fi prelucrat? corect ?i partea ?ntreag?. Codul care trebuie s? fie inserat ?n sec?iunea public a clasei rational_fara_semn arat? astfel:

rational_fara_semn
    rational_fara_semn::operator = (const rational_fara_semn &y)
{
   part_int=y.part_int;
   numarat=y.numarat; // y.numarat - este accesibil
   numit=y.numit;     // y.numit   - este accesibil
   reducere();
   return *this;
}
 
rational_fara_semn
    rational_fara_semn::operator = (const fractie_rationala &y)
{
   part_int=0;
   numarat=y.numarator(); // y.numarat - nu este accesibil
   numit=y.numitor();     // y.numit   - nu este accesibil
   reducere();
   return *this;
}

Dac? ve?i ad?uga la func?ia main() urm?torul cod de verificare:

   d=rational_fara_semn(2, 4, 3);
   cout << "d=" << d << endl;
   e=fractie_rationala(8, 3);
   cout << "e=" << e << endl;

ve?i mai ob?ine la ie?ire urm?torul text:

d=3,1/3

e=2,2/3

Dup? cum observ?m, valoarea 2,4/3 (doi ?ntregi ?i patru treimi) la atribuire s-a transformat ?n 3,1/3 (trei ?ntregi ?i o treime), iar valoarea 8/3 (opt treimi) la atribuire s-a transformat ?n 2,2/3 (doi ?ntregi ?i dou? treimi).

Exerci?iul 7.7. Suprascrie?i ?i supra?nc?rca?i operatorul de atribuire = ?n clasa derivat? rational.

Cu p?rere de r?u, nu vom putea supra?nc?rca operatorul de atribuire = ?n a?a mod ca s? avem posibilitatea de a atribui de la clasa derivat? (?n cazul nostru - rational_fara_semn) la clasa de baz? (?n cazul nostru fractie_rationala), fiindc? acest operator poate fi supra?nc?rcat numai sub form? de func?ie membr? (?n acest caz avem c? este a clasei de baz?), iar ?n clasa de baz? fractie_rationala nu este o a?a func?ie membr?. Mai mult ca at?t, ea nici nu poate exista, din considerentul c? ?n timp ce a fost creat? clasa de baz? nu s-a ?tiut nimic despre clasa derivat?, care a ap?rut mai t?rziu.

Totu?i, ?n cercetarea noastr? ar fi fost natural s? avem posibilitatea de a atribui, de exemplu, valoarea 2,1/3 unui obiect fractie_rationala, care ?n acest caz devine 7/3. Acest lucru poate fi f?cut astfel: cre?m ?n clasa derivat? o func?ie membr? public? care converte?te valoarea rational_fara_semn ?n fractie_rationala

   fractie_rationala rational_fara_semn::la_fr()
   {
    return fractie_rationala(part_int*numit+numarat, numit);
      }
// ?i/sau o func?ie prieten? care face acela?i lucru:
   friend fractie_rationala la_fr(const rational_fara_semn &y)
   {
      return fractie_rationala(y.part_int*y.numit+y.numarat, y.numit);
   }
// apoi folosim una din aceste func?ii, sau ambele, la atribuire: 
   f1=rational_fara_semn(2, 1, 3).la_fr(); // se folose?te membr?
   cout << "f1=" << f1 << endl;
   f2=la_fr(rational_fara_semn(2, 1, 3));  // se folose?te prieten?
   cout << "f2=" << f2 << endl;

Rezultatul va fi:

f1=7/3

f2=7/3

Exerci?iul 7.8. G?ndi?i-v? cum poate fi rezolvat? aceast? problem? ?n clasa rational.

Acum trecem la examinarea operatorului de conversie, care neap?rat trebuie s? fie suprascris ?n clasa derivat? rational_fara_semn, lu?nd ?n considera?ie ?i partea ?ntreag?. Inser?m ?n sec?iunea public a clasei rational_fara_semn urm?torul cod:

rational_fara_semn::operator double ()
   {
     return (double)(numarat+part_int*numit)/numit;
   }

Totodat?, suprascriem acest operator ?i ?n clasa rational, ad?ug?nd ?n sec?iunea public a acestei clase urm?torul cod:

rational::operator double ()
   {
     double d = (double)(numarat + part_int * numit)/numit;
     return semn == '+' ? d : -d;
   }

Observ?m c? aici s-a luat ?n considera?ie ?i semnul num?rului. Demonstr?m lucrul acestui operator ?n clasele rational_fara_semn ?i rational. Ad?ug?m la func?ia main() urm?torul fragment:

cout << rational_fara_semn(2, 1, 3) << " = "
     << (double) rational_fara_semn(2, 1, 3)
     << endl;
 
   cout << rational(-1, 2, 3) << " = "
        << (double)rational(-1, 2, 3) 
        << endl;

Acest fragment afi?eaz? urm?torul text:

2,1/3 = 2.33333

-1,2/3 = -1.66667

Acum avem posibilitatea de a compara obiectele fractie_rationala, rational_fara_semn, rational unul cu altul ?n orice combina?ie. Pentru exemplu, ad?ug?m la func?ia main() urm?torul cod:

if(fractie_rationala(7, 2) > rational_fara_semn(2, 1, 3))
   cout << fractie_rationala(7, 2) << " > "
        << rational_fara_semn(2, 1, 3) << endl;
else
   cout << fractie_rationala(7/2) << " <= "
        << rational_fara_semn(2, 1, 3) << endl;
 
if(rational('-', 0, 1, 2) >= rational_fara_semn(0, 1, 2))
   cout << rational('-', 0, 1, 2) << " >= "
        << rational_fara_semn(0, 1, 2) << endl;
else
   cout << rational('-', 0, 1, 2) << " < "
        << rational_fara_semn(0, 1, 2) << endl;

Acest cod va afi?a:

7/2 > 2,1/3

-1/2 < 1/2

Posibilitatea de a compara frac?iile ra?ionale va fi folosit? ?n Capitolul 8 (despre polimorfism ?i func?ii virtuale).

Exerci?iul 7.9. Ceilal?i operatori, supra?nc?rca?i ?n clasa de baz? fractie_rationala ?i care nu au fost examena?i cu scopul de a-i suprascrie ?i/sau supra?nc?rca ?n clasa derivat? rational_fara_semn, ?i ve?i cerceta de sine st?t?tor. La fel, ve?i decide necesitatea de suprascriere ?i/sau supra?nc?rcare a lor ?n clasa rational.

?n afara de operatorii mo?teni?i de la clasa de baz? (nu conteaz? cu supra?nc?rcare sau f?r?), ?n clasa derivat? se pot fi supra?nc?rca?i suplimentar ?i ceilal?i operatori, care pot fi supra?nc?rca?i ?n principiu (ceea ce nu s-a f?cut ?n clasa de baz?).

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

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

Ваш 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 сайтов