Home - Rasfoiesc.com
Educatie Sanatate Inginerie Business Familie Hobby Legal
Doar rabdarea si perseverenta in invatare aduce rezultate bune.stiinta, numere naturale, teoreme, multimi, calcule, ecuatii, sisteme




Biologie Chimie Didactica Fizica Geografie Informatica
Istorie Literatura Matematica Psihologie

C


Index » educatie » » informatica » C
» Supraincarcarea operatorilor de conversie


Supraincarcarea operatorilor de conversie


Supraincarcarea operatorilor de conversie

Utilizarea unui constructor pentru a specifica o conversie de tip este posibila pentru un numar limitat de situatii deoarece:

Nu exista o conversie implicita de la un tip definit de utilizator (clasa) la un tip predefinit.

Nu se poate defini o conversie de la un tip nou de date la un tip definit mai inainte, fara modificarea tipului vechi.



Aceste probleme se pot rezolva prin definirea unui operator de conversie al clasei. Intr-o clasa X, o functie membra X::operator T(), unde T este un nume de tip (predefinit sau definit de utilizator) realizeaza conversia de la tipul X la tipul T, in modul descris de functia operator. Se pot diferentia doua categorii de operatori de conversie: conversie dintr-un tip definit de utilizator intr-un tip predefinit si conversie dintr-un tip definit de utilizator in alt tip definit de utilizator.

Conversia dintr-un tip definit de utilizator intr-un tip predefinit

Una din utilizarile frecvente ale operatorilor de conversie este aceea de a converti un tip definit de utilizator (clasa) intr-un tip predefinit printr-o functie membra nestatica a clasei respective. O astfel de functie nu are nici un argument, dat fiind ca operatorul de conversie este un operator unar (foloseste numai obiectul pentru care a fost apelat, al carui pointer this il primeste implicit).

Pentru o clasa data se pot supraincarca mai multi operatori de conversie de la clasa respectiva la unul din tipurile predefinite. Conversia definita prin supraincarcarea operatorului de conversie poate fi apelata explicit sau implicit. Apelul explicit al operatorului de conversie pentru un obiect din clasa X catre tipul predefinit T poate avea doua forme:

T(obiect) sau T(obiect)

Conversia implicita (deci apelul implicit al functiei operator de conversie) are loc la utilizarea unui obiect dintr-o clasa in care s-a definit o astfel de functie intr-o expresie aritmetica sau conditionala. Daca sunt definite mai multe functii operatori de conversie pot sa apara ambiguitati in selectarea uneia dintre acestea in cazul conversiei implicite. Cateva situatii de conversie sunt prezentate in exemplul urmator.

Exemplul 7

Se completeaza clasa Point cu definirea catorva operatori de conversie, care apoi sunt apelati in diferite modalitati.

class Point;

Point::operator double()

Point::operator void*()

void f8()

Se poate evita eroarea de compilare determinata de ambiguitatea la conversia implicita din instructiunea if(p1) fortand in mod explicit unul dintre operatorii de conversie ai clasei, de exemplu astfel if ((void*)p1)

Conversia dintr-un tip definit de utilizator intr-un alt tip definit de utilizator

Fie doua clase X si Y. Conversia obiectelor de tip X in obiecte de tip Y se poate realiza fie prin utilizarea constructorilor, fie prin supraincarcarea operatorului de conversie in clasa Y

Daca in clasa Y se defineste un constructor de tipul Y(X ob), atunci se poate realiza o conversie a unui obiect de tip X intr-un obiect de tip Y. Pentru accesul la datele private sau protected ale clasei X, este necesar declararea friend class Y in clasa X

n Exemplul 8

Se considera clasa Point, definita in aceasta sectiune si clasa Complex, definita in sectiunea 2. Conversia datelor intre cele doua tipuri are si o semnificatie matematica bine precizata, dat fiind ca un numar complex poate fi reprezentat printr-un punct intr-un plan bidimensional (imaginea numarului complex). Modul in care se realizeaza conversia datelor de tip Complex in date de tip Point, deci calculul imaginii unui numar complex, este prezentata in continuare.

class Complex

Complex(double r, double i)

friend class Point;

class Point

void f9()

n

Conversia dintr-un tip definit de utilizator intr-un alt tip definit de utilizator se poate realiza si prin supraincarcarea operatorului de conversie. Pentru conversia obiectelor de tip X in obiecte de tip Y, in clasa X se defineste functia operator de conversie

X::operator Y();

Pentru ca aceasta functie membra nestatica a clasei X sa aiba acces la date private sau protejate ale clasei Y, ea se declara functie friend in clasa Y

In exemplul urmator se reia operatia de conversie din clasa Complex in clasa Point prin supraincarcarea operatorului cu conversie in clasa Complex

n Exemplul 9

class Point;

class Complex

Complex(double r, double i)

operator Point();

class Point ;

Complex::operator Point()

void f10()

Se construieste mai intai obiectul p1 folosind constructorul implicit; instructiunea p1 = c1 apeleaza operatorul de conversie la tipul Point definit in clasa Complex; dupa aceasta conversie mai este apelata functia operator de asignare a clasei Point, care, la returnare, construieste un obiect temporar folosind constructorul de copiere al clasei Point

n

Este de mentionat faptul ca este admisa definirea unei singure conversii de la un tip de date la altul. Daca in Exemplul 9 s-ar pastra si constructorul de conversie definit in Exemplul 8, atunci ar apare o eroare de compilare.

Se poate observa ca, in unele cazuri, o valoare de un tip dorit poate fi construita prin utilizarea repetata a constructorilor si operatorilor de conversie. Dintre acestea, o singura conversie implicita definita de utilizator este legala. Situatiile in care un obiect poate fi construit in mai multe feluri sunt ilegale (mesajul de eroare de compilare se refera la o ambiguitate).

Exercitii

E1 Pentru clasa Point, sa se defineasca urmatoarele operatii folosind supraincarcarea unor operatori:

Rotatia vectorului cu un unghi u

Calculul lungimii vectorului.

E2    Fie urmatoarea functie:

void f3();

String sir(v);

cout << sir;

Cum se explica eroarea care apare la executia acestei functii?

Sa se defineasca un alt constructor al clasei String care sa poata fi folosit in astfel de situatii.

E3 Pentru clasa String sa se defineasca urmatoarele operatii de comparatie folosind functii operator friend

int operator ==( const String& s1, const String& s2 );

int operator ==( const String& s1, const char* s2 );

int operator ==( const char* s1, const String& s2 );

int operator !=( const String& s1, const String& s2 );

int operator !=( const String& s1, const char* s2);

int operator !=( const char* s1, const String& s2);

int operator <( const String& s1, const String& s2 );

int operator <( const String& s1, const char* s2);

int operator <( const char* s1, const String& s2);

int operator >( const String& s1, const String& s2 );

int operator >( const String& s1, const char* s2 );

int operator >( const char* s1, const String& s2 );

int operator <=( const String& s1, const String& s2 );

int operator <=( const String& s1, const char* s2);

int operator <=( const char* s1, const String& s2);

int operator >=( const String& s1, const String& s2 );

int operator >=( const String& s1, const char* s2 );

int operator >=( const char* s1, const String& s2 );

Valoarea returnata este diferita de 0 daca cele doua obiecte String indeplinesc conditia de comparatie si este 0 in toate celelate cazuri. Pentru argumentele de tipul (const char* s) se considera pointerii la siruri terminate cu nul.

E5 Pentru clasa String sa se defineasca operatia de concatenare a doua siruri folosind functii friend operator+(). Valoarea returnata este un obiect nou de tip String, al carui sir reprezinta concatenarea sirurilor continute de cele doua argumente

String operator +( const String& s1, const String& s2);

String operator +( const char* s1, const String& s2);

String operator +( const String& s1, const char* s2);

Se considera pointerii la siruri terminate cu nul.

E6 Pentru clasa String sa se defineasca operatia de adaugare a unui sir nou la sfarsitul unui sir existent folosind functii friend operator+=()

const String& operator +=( const String& s );

const String& operator +=( const char* s);

Se considera pointerii la siruri terminate cu nul.

E7 Sa se defineasca urmatoarele functii de cautare a unui caracter sau a unui subsir ale clasei String:

int FindChar(char c) const;

int Find(const char* subsir) const;

int Find(const String s) const;

int FindReverse(char c) const;

int FindReverse(const char* subsir)const;

int FindReverse(const String s)const;

Pointerii subsir trebuie sa fie pointeri la siruri terminate cu nul. Functia Find(char c) returneaza indexul primului caracter cu valoarea c dintr-un obiect String, sau -1 daca obiectul String nu contine acest caracter. Celelate doua functii Find() returneaza indexul primului caracter in sirul de caractere al unui subsir dat prin pointer la caracter sau ca un obiect String, daca acest subsir este continut in sirul dat, sau -1, daca nu exista un astfel de subsir.

Functiile FindReverse() sunt definite in mod asemanator, cu diferenta ca se executa o cautare de la sfarsitul sirului.

E8    In clasa String, sa se defineasca urmatoarele functii:

int GetLength(); // returneaza nr. caractere al sirului

// fara caracterul nul terminal

char *GetBuffer(); // returneaza bufferul de caractere

void MakeUpper();    // converteste in majuscule

void MakeLower();    // converteste in litere mici

void MakeReverse();// inverseaza caracterele in sir

E9 Sa se defineasca un iterator pentru clasa String






Politica de confidentialitate




Copyright © 2024 - Toate drepturile rezervate