3.4. Definirea ?i supra?nc?rcarea constructorului

3.4. Definirea ?i supra?nc?rcarea constructorului

Mai dezvolt?m clasa fractie_rationala, d?nd posibilitate constructorului de a ini?ializa c?mpurile numarat ?i numit. Vom lua ?n considera?ie c? numitorul nu poate lua valoarea 0:

#include "iostream.h"
#include "stdlib.h"
 
class fractie_rationala
{
   protected:
      unsigned int numarat;
      unsigned int numit;
   public:
      fractie_rationala(unsigned int, 
                        unsigned int);
   private:
      void eroare(char* mesaj);
};
 
fractie_rationala::fractie_rationala(unsigned int numarat_init,
                                     unsigned int numit_init)
{
   if(numit_init!=0)
   {
      numarat=numarat_init; // ini?ializarea num?r?torului
      numit=numit_init;     // ini?ializarea numitorului
   }
   else
      eroare("Numitorul este egal cu zero!");
}
 
void fractie_rationala::eroare(char* mesaj)
{
   // trimiterea mesajului ?n fluxul standard pentru mesaje de erori  
   cerr << mesaj;       
   exit(1);  // ie?ire for?at? din program  
}  
void main() {
    fractie_rationala fr1;       // aceast? instruc?iune este gre?it? 
    fractie_rationala fr2(2, 3); // crearea corect? a obiectului        
    fr1 = fr2;        
    char c;     
    cin >> c;
}


?n primul r?nd, observ?m c? s-a schimbat antetul constructorului. Acum constructorul accept? ca argumente dou? valori de tipul unsigned int. Valoarea parametrului numarat_init reprezint? valoarea de ini?ializare pentru num?r?tor (c?mpul numarat al clasei), iar valoarea parametrului numit_init reprezint? valoarea de ini?ializare pentru numitor (c?mpul numit al clasei).

Constructorul verific? ?nt?i de toate dac? valoarea parametrului numit_init este diferit? de zero. Numai dac? aceast? condi?ie are loc el ?nscrie valorile de ini?ializare ?n c?mpurile clasei. Cazul ?n care utilizatorul ?nt?mpl?tor a pus pe 0 valoarea parametrului numarat_init va fi prins de c?tre constructor. ?n acest caz, constructorul apeleaz? func?ia eroare() transmi??nd prin parametru mesajul respectiv.

Func?ia eroare() este func?ia membr? a clasei fractie_rationala ?i a fost introdus? pentru prelucrarea situa?iilor de eroare (precum este cazul descris mai sus). Antetul acestei func?ii a fost declarat ?n sec?iunea de declarare a membrilor priva?i (private). Aceasta ?nseamn? c? ea poate fi apelat? numai din alte func?ii membre ale clasei fractie_rationala sau din func?ii de tip prieten al acestei clase (?n exemplul dat clasa noastr? nu are a?a func?ii, func?iile prietene vor fi analizate ?n 4.3).

Atrage?i aten?ia ?nc? o dat? cum se apeleaz? func?ia eroare() ?n constructorul clasei fractie_rationala: doar numele func?iei, iar ?n paranteze – argumentul. A?a ea poate fi apelat? din orice alt? func?ie membr? a clasei fractie_rationala, fiindc? aici este cunoscut? ?i accesibil? (bine?n?eles, clasa dat? ?n exemplul respectiv nu are alte func?ii membre dec?t constructorul, destructorul implicit ?i eroare()).

Lua?i ?n considera?ie urm?torul moment. Descriind anteturile func?iilor membre ?n declara?ia clasei, putem indica numai tipurile parametrilor (cum este prototipul constructorului) sau ?i tipurile ?i denumirile parametrilor (cum este antetul func?iei eroare()). ?n exemplul nostru, special au fost ar?tate ambele posibilit??i. ?ns?, ?n anteturile la defini?iile func?iilor trebuie numaidec?t de scris ?i tipurile, ?i denumirile parametrilor. Mai mult dec?t at?t, la definirea func?iilor tipurile ?i denumirile parametrilor trebuie s? coincid? cu respectivele la descrierea prototipurilor acestor func?ii ?n declararea clasei. Ceea ce a ?i fost ar?tat ?n exemplul dat.

Memoriza?i bine cum se scriu anteturile func?iilor membre la realizarea lor. Linia:

fractie_rationala::fractie_rationala …

?nseamn? c? descriem constructorul (?nainte de :: denumirea clasei, dup? :: denumirea func?iei membr?, ?n cazul nostru – constructorul). Constructorul nu poate avea tip, ca ?i destructorul. Linia:

void fractie_rationala::eroare(char* mesaj)

?nseamn? c? descriem func?ia eroare() care este membr? a clasei fractie_rationala. Func?ia ?n cazul nostru are tipul void, adic? nu ?ntoarce nici o valoare.

?nc? un moment foarte important! Instruc?iunea:

fractie_rationala fr1;

care creeaz? obiectul fr1 ?n func?ia main() ?i care era corect? ?n exemplele precedente, ?n exemplul acesta va fi gre?it?. Cauza este urm?toarea: ?n clasa fractie_rationala este declarat cel pu?in un constructor; astfel, compilatorul nu mai creeaz? constructorul implicit (f?r? parametri). Instruc?iunea sus-numit? va fi ?n?eleas? de c?tre compilator ca o indica?ie pentru crearea obiectului fr1 cu apelarea simultan? a constructorului f?r? parametri. Dar, un astfel de constructor nu exist? ?n clasa fractie_rationala ?i compilatorul va afi?a un mesaj de eroare, ceva de tipul: „Could not find a match for fractie_rationala::fractie_rationala()”, ceea ce semnific? c? el nu g?se?te varianta constructorului f?r? parametri.

Sunt dou? ie?iri din aceast? situa?ie:

1) Modific?m exemplul de mai sus, ad?ug?nd ?n clasa fractie_rationala ?nc? un constructor, dar f?r? parametri. Pentru aceasta, ?n sec?iunea de descriere a membrilor deschi?i, dup? linia:

public:

ad?ug?m linia:

fractie_rationala();

iar dup? declararea clasei inser?m realizarea acestui constructor:

fractie_rationala::fractie_rationala()
{
   numarat=0; // ini?ializarea num?r?torului cu 0
   numit=1;   // ini?ializarea numitorului cu 1
}


Adic?, constructorul f?r? parametri ini?ializeaz? obiectul cu valoarea 0/1. ?n a?a mod am programat. Alt? solu?ie era de a ini?ializa obiectul cu valoarea 1/1, sau cu orice alt? valoare corect?. Acum instruc?iunea:

fractie_rationala fr1;

a devenit din nou corect?. Ea creeaz? obiectul fr1, ini?ializ?ndu-l cu valoarea 0/1 prin apelarea din cei doi constructori a constructorului f?r? parametri.

2) ?n loc s? introducem doi constructori, l?s?m numai unul, indic?nd valorile implicite pentru parametri. La definire modific?m doar antetul constructorului ?n felul urm?tor:

fractie_rationala::fractie_rationala(unsigned int numarat_init=0, 
                                     unsigned int numit_init=1)


Aceasta ?nseamn? c? la apelul constructorului putem da dou? valori, sau numai o valoare pentru primul argument (consim?ind la valoarea implicit? pentru al doilea), sau nici o valoare (consim?ind la cele implicite pentru ambele argumente). Adic?, obiectul poate fi creat a?a:

fractie_rationala fr1(3, 5); // valoarea ini?ial? este 3/5
sau a?a:
fractie_rationala fr1(2);    // valoarea ini?ial? este 2/1
sau a?a:
fractie_rationala fr1;       // valoarea ini?ial? este 0/1
Mai exist? ?nc? o posibilitate:
fractie_rationala fr1=2;     // valoarea ini?ial? este 2/1


Ultima variant? provine de la forma special?, ad?ug?toare, de apelare a constructorilor cu un singur parametru. Constructorul nostru are doi parametri, iar dac? pentru un obiect oarecare ne aranjeaz? valoarea implicit? a parametrului doi, putem indica numai primul argument sau astfel:

fractie_rationala fr(5);
sau:
fractie_rationala fr=5; // forma special? de apelare a
// constructorului cu un singur parametru


Aceste dou? instruc?iuni sunt echivalente.

Valorile implicite pentru fiecare parametru pot fi indicate numai ?ntr-un singur loc, sau ?n declararea clasei, ori la definirea constructorului. Valoarea implicit? pentru parametrul concret poate fi indicat? numai dac? sunt deja concretizate valorile implicite pentru to?i parametrii din partea dreapta a lui. Adic?, pentru constructorul nostru se admit numai urm?toarele perechi de anteturi – respectiv, ?n declararea clasei ?i ?n descrierea constructorului:

1)

fractie_rationala(unsigned int numarat_init, 
                  unsigned int numit_init);
cu
fractie_rationala::fractie_rationala(unsigned int numarat_init,
                                     unsigned int numit_init)


Nu au fost indicate valorile implicite pentru parametri;

2)

fractie_rationala(unsigned int numarat_init,
                  unsigned int numit_init=1);
cu
fractie_rationala::fractie_rationala(unsigned int numarat_init,
                                     unsigned int numit_init)


Valoarea implicit? a fost indicat? numai pentru parametrul doi ?n declararea clasei;

3)

fractie_rationala(unsigned int numarat_init,
                  unsigned int numit_init);
cu
fractie_rationala::fractie_rationala(unsigned int numarat_init,
                                     unsigned int numit_init=1)


Valoarea implicit? a fost indicat? numai pentru parametrul doi la descrierea constructorului;

4)

fractie_rationala(unsigned int numarat_init=0,
                  unsigned int numit_init=1);
cu
fractie_rationala::fractie_rationala(unsigned int numarat_init,
                                     unsigned int numit_init)


Valorile implicite au fost indicate pentru ambii parametri ?n declararea clasei;

5)

fractie_rationala(unsigned int numarat_init,
                  unsigned int numit_init);
cu
fractie_rationala::fractie_rationala(unsigned int numarat_init=0,
                                     unsigned int numit_init=1)


Valorile implicite au fost indicate pentru ambii parametri la descrierea constructorului;

6)

fractie_rationala(unsigned int numarat_init,
                  unsigned int numit_init=1);
cu
fractie_rationala::fractie_rationala(unsigned int numarat_init=0,
                                     unsigned int numit_init)


Valorile implicite au fost indicate pentru parametrul doi ?n declararea clasei ?i pentru primul parametru la definirea constructorului.

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