La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a. a

Presentazioni simili


Presentazione sul tema: "FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a. a"— Transcript della presentazione:

1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a. a
FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Overloading degli Operatori

2 Overloading degli Operatori
Definizione: L’overloading degli operatori serve a definire, per mezzo degli operatori tradizionali, le operazioni che coinvolgono i dati dei tipi nuovi definiti dall’utente. Gli operatori utilizzabili sono cioè quelli già definiti come tali nel C++ e la ridefinizione delle operazioni che essi potranno eseguire non influirà sulla loro: precedenza, associatività, e numero di operandi. Metodo per l’overloading L’overloading di un operatore si ottiene definendo una funzione con il nome composto dalla parola riservata operator seguita dall’operatore da ridefinire (ad es.: operator+, operator*, ..ecc.)

3 Overloading degli Operatori
Ridefinibilità degli operatori: Tutti gli operatori possono essere ridefiniti, tranne i seguenti: . .* :: ?: sizeof Tipologia delle funzioni di overloading degli operatori: Le funzioni di overloading degli operatori: devono essere funzioni membro di una classe per tutti gli operatori di assegnazione e per gli operatori: ( ) [ ] -> devono essere funzioni non membro (da dichiarare se possibile friend, per migliorarne l’efficienza) quando si ridefiniscono con cout e cin gli operatori: << >> possono essere sia funzioni membro che non membro (da dichiarare se possibile friend, per migliorarne l’efficienza) per tutti gli altri operatori.

4 Overloading degli Operatori
Nota: E’ bene tener presente che nel caso di funzione di overloading di operatore, definita come funzione membro, essa non può essere dichiarata static. Operatività dell’overloading degli operatori: Un operatore ridefinito per gli oggetti di una determinata classe viene richiamato quando: nel caso di operatore binario, l’operando sinistro è un oggetto della classe, oppure: nel caso di operatore unario, l’unico operando è un oggetto della classe.

5 Overloading degli Operatori
Overloading di operatori binari con funzioni membro: La funzione di ridefinizione dell’operatore assume la forma: Prototipo: Tipo_Restituito operator Segno_Operatore (Tipo_Argomento); Implementazione: Tipo_Restituito operator Segno_Operatore (Tipo_Argomento Variabile_Argomento) {……codice della funzione...…} La suddetta implementazione viene invocata quando in una espressione: …. Variabile1 Segno_Operatore Variabile2 …. la Variabile1 (almeno) è un oggetto della classe e, in tal caso, l’invocazione assume la forma: …… Variabile1. operator Segno_Operatore (Variabile2)…..

6 Overloading degli Operatori
Overloading di operatori binari con funzioni membro: Nell’ambito del codice della funzione membro di nome: “operatorSegno_Operatore” si ha l’accesso immediato a tutti i dati membro pubblici e privati relativi all’oggetto Variabile1 (che è l’oggetto per cui viene invocata la funzione), mentre gli stessi dati sono accedibili per l’oggetto Variabile2 selezionandoli con il nome dell’oggetto stesso (ossia con: Variabile2 . Nome_dato) Mediante i suddetti accessi ai dati membro degli oggetti Variabile1 e Variabile2 è possibile ridefinire il Segno_Operatore facendogli fare una operazione diversa da quella originale, e restituendo, poi, una variabile del tipo indicato nel prototipo.

7 Overloading degli Operatori
Esempio di overloading di operatori binari con funzioni membro: #include <iostream.h> class Cmplex { public: Cmplex (int, int); Cmplex operator+ (Cmplex); Cmplex operator= (Cmplex); int r,i;}; Cmplex::Cmplex (int rea, int ima){ r= rea; i= ima;}

8 Overloading degli Operatori
Cmplex Cmplex::operator+ (Cmplex c2){ Cmplex csum (0, 0); csum.r= r + c2.r; csum.i= i + c2.i; return csum;} Cmplex Cmplex::operator= (Cmplex d){ return Cmplex (d.r, d.i);} int main(){ Cmplex a(5, 5); Cmplex b(2, 2); Cmplex c(0, 0); c= a+b; cout<<c.r<<"+i"<<c.i<<endl; return 0;}

9 Overloading degli Operatori
Overloading di operatori binari con funzioni non membro: La funzione di ridefinizione dell’operatore assume la forma: Prototipo: Tipo_Restituito operator Segno_Operatore (Tipo_Argomento, Tipo_Argomento); Implementazione: Tipo_Restituito operator Segno_Operatore (Tipo_Argomento1 Variabile_Argomento1, Tipo_Argomento2 Variabile_Argomento2 ) {……codice della funzione...…} La suddetta implementazione viene invocata quando in una espressione: …. Variabile1 Segno_Operatore Variabile2 …. la Variabile1 (almeno) è un oggetto della classe e, in tal caso, l’invocazione assume la forma: …… operator Segno_Operatore (Variabile1, Variabile2)…..

10 Overloading degli Operatori
Overloading di operatori binari con funzioni non membro: Nell’ambito del codice della funzione non membro di nome: “operatorSegno_Operatore” si ha l’accesso a tutti i dati membro pubblici (e anche privati, se la funzione è stata definita friend) relativi agli oggetti Variabile1 e Variabile2, selezionandoli con il nome degli oggetti stessi (ossia con: Variabile1 . Nome_dato, Variabile2 . Nome_dato). Mediante i suddetti accessi ai dati membro degli oggetti Variabile1 e Variabile2 è possibile ridefinire il Segno_Operatore facendogli fare una operazione diversa da quella originale, e restituendo, poi, una variabile del tipo indicato nel prototipo.

11 Overloading degli Operatori
Esempio di overloading di operatori binari con funzioni non membro: #include <iostream.h> class Complesso { friend Complesso operator+ (Complesso, Complesso); public: Complesso (int=0, int=0); Complesso operator= (Complesso); int getReal ( ) {return r;} int getImagin ( ) {return i;} private: int r,i;}; Complesso::Complesso (int a, int b){ r= a; i= b;}

12 Overloading degli Operatori
Complesso operator+ (Complesso ca, Complesso cb){ int re= ca.r + cb.r; int im= ca.i + cb.i; return Complesso (re, im);} Complesso Complesso::operator= (Complesso cm){ return Complesso (cm.r, cm.i);} int main ( ){ Complesso c1(4, 5); Complesso c2(6, 7); Complesso c3= c1 + c2; cout << c3.getReal( ) << "+i" << c3.getImagin ( ) <<"\n"; return 0;}

13 Overloading degli Operatori
Overloading di operatori unari con funzioni membro: La funzione di ridefinizione dell’operatore assume la forma: Prototipo: Tipo_Restituito operatorSegno_Operatore ( ); Implementazione: Tipo_Restituito operatorSegno_Operatore ( ) {……codice della funzione...…} La suddetta implementazione viene invocata quando in una espressione: …. Segno_Operatore Variabile …. la Variabile è un oggetto della classe e, in tal caso, l’invocazione assume la forma: …… Variabile . operatorSegno_Operatore ( )…..

14 Overloading degli Operatori
Overloading di operatori unari con funzioni membro: Nell’ambito del codice della funzione membro di nome: “operatorSegno_Operatore” si ha l’accesso immediato a tutti i dati membro pubblici e privati relativi all’oggetto Variabile (che è l’oggetto per cui viene invocata la funzione). Mediante i suddetti accessi ai dati membro dell’oggetto Variabile è possibile ridefinire il Segno_Operatore facendogli fare una operazione diversa da quella originale, e restituendo, poi, una variabile del tipo indicato nel prototipo.

15 Overloading degli Operatori
Esempio di overloading di operatori unari con funzioni membro: #include <iostream.h> class Angle{ public: Angle (int=0); Angle operator* ( ); int get( ); private: int arc;}; Angle::Angle (int a) {arc= a;}

16 Overloading degli Operatori
Angle Angle::operator* ( ){ arc= (arc % 360); return Angle(arc);} int Angle::get( ){ return arc;} int main ( ){ Angle arco(50); arco= *arco ; cout << arco.get( ); return 0;}

17 Overloading degli Operatori
Overloading di operatori unari con funzioni non membro: La funzione di ridefinizione dell’operatore assume la forma: Prototipo: Tipo_Restituito operatorSegno_Operatore (Tipo_Argomento); Implementazione: Tipo_Restituito operatorSegno_Operatore (Tipo_Argomento Variabile_Argomento) {……codice della funzione...…} La suddetta implementazione viene invocata quando in una espressione: …. Segno_Operatore Variabile …. la Variabile è un oggetto della classe e, in tal caso, l’invocazione assume la forma: …… operator Segno_Operatore (Variabile)…..

18 Overloading degli Operatori
Overloading di operatori unari con funzioni non membro: Nell’ambito del codice della funzione non membro di nome: “operatorSegno_Operatore” si ha l’accesso a tutti i dati membro pubblici (e anche privati, se la funzione è stata definita friend) relativi all’oggetto Variabile, selezionandoli con il nome dell’oggetto stesso (ossia con: Variabile . Nome_dato). Mediante i suddetti accessi ai dati membro dell’oggetto Variabile è possibile ridefinire il Segno_Operatore facendogli fare una operazione diversa da quella originale, e restituendo, poi, una variabile del tipo indicato nel prototipo.

19 Overloading degli Operatori
Esempio di overloading di operatori unari con funzioni non membro: #include <iostream.h> class Angle { public: Angle (int= 0); int get ( ); private: int arc;}; Angle::Angle (int a) {arc= a;} int Angle::get ( ) {return arc;}

20 Overloading degli Operatori
Angle operator* (Angle val) {int compl= (val.get( ) % 360); return Angle (compl);} int main ( ) {Angle arco (60); arco= *arco; cout << arco.get( ); return 0;}

21 Overloading degli Operatori
Conversione tra tipi diversi: Nel caso dei tipi predefiniti la conversione di una variabile di un tipo ad una di tipo diverso si ottiene esplicitamente con l’operatore static_cast, nel modo seguente: …….. static_cast <TipoB> (Variabile_TipoA) ……. questa espressione crea un oggetto temporaneo del TipoB a partire dalla Variabile_TipoA. Nel caso di tipi definiti dall’utente, la stessa cosa, ossia la conversione da un tipo definito dall’utente ad un tipo primitivo, o viceversa, oppure ad un tipo ancora definito dall’utente, può ottenersi con i costruttori di conversione, che ricevono un solo argomento e che convertono gli oggetti di altri tipi (inclusi i tipi predefiniti) in oggetti di una determinata classe.

22 Overloading degli Operatori
Conversione tra tipi diversi con l’operatore di conversione: La conversione nel caso di tipi definiti dall’utente può anche ottenersi per mezzo di un opportuno operatore di conversione (o di cast), da costruire con una funzione membro non static, che deve essere realizzata e richiamata come indicato nel seguito. L’ operatore di conversione viene anche esso definito per mezzo della parola riservata operator che, questa volta, non viene utilizzata in connessione con un operatore da ridefinire, ma con un tipo (o oggetto) verso il quale si vuole definire una conversione.

23 Overloading degli Operatori
Conversione tra tipi diversi con l’operatore di conversione: Prototipo: operator TipoB ( ); Nota: non serve indicare che la funzione restituisce un oggetto di TipoB perché ciò è implicito nel fatto che la funzione, come sopra definita, converte un altro oggetto in un oggetto di TipoB Implementazione: Nome_Classe ::operator TipoB ( ) {….implementazione della conversione….…..return Dato_TipoB;} Nota: il codice di implementazione della conversione opera sui dati membro pubblici e privati relativi all’oggetto per il quale la funzione operator TipoB viene invocata. Invocazione: …(TipoB) Oggetto_TipoA… che il compilatore traduce in: ...Oggetto_TipoA.operator TipoB ( )….

24 Overloading degli Operatori
Esempio di conversione tra tipi diversi: #include<iostream.h> class Complesso { public: Complesso (int, int); operator int ( ) ; private: int r, i;}; Complesso::Complesso (int a, int b){ r= a; i= b;} Complesso::operator int ( ) { return (i*i + r*r);}

25 Overloading degli Operatori
int main ( ) { Complesso c(2, 3); int k= (int) c; cout<<k<<"\n"; //Presenta 13. return 0;}

26 Overloading degli Operatori
L’overloading degli operatori ++ e - - Gli operatori ++ e - - operano come operatori di preincremento e predecremento nel caso che essi precedano la variable a cui si applicano. In questo caso il loro overloading non differisce da quello tradizionale degli operatori unari. Nel caso che essi seguano la variabile a cui si applicano essi invece operano come post incremento e post decremento e, quindi, la loro operatività va distinta da quella precedente. In questo secondo caso la distinzione si attua come indicato nelle pagine che seguono.

27 Overloading degli Operatori
Nel caso di post incremento (ma lo stesso vale per il post decremento), se l’overloading è implementato come funzione membro, quando s’incontra l’espressione: Variabile ++ il compilatore genera l’invocazione a funzione: Variabile . operator++ (0) il cui prototipo sarà: Tipo_Restituito operator++ (int); dove lo 0 è soltanto un valore fittizio necessario per distinguere il post incremento dal preincremento.

28 Overloading degli Operatori
Nel caso di post incremento (ma lo stesso vale per il post decremento), se l’overloading è implementato come funzione non membro, quando s’incontra l’espressione: Variabile ++ il compilatore genera l’invocazione a funzione: operator++ (Variabile, 0) il cui prototipo sarà: Tipo_Restituito operator++ (Tipo_Variabile, int); dove, anche in questo caso, lo 0 è soltanto un valore fittizio necessario per distinguere il post incremento dal preincremento.


Scaricare ppt "FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a. a"

Presentazioni simili


Annunci Google