| | | OFFLINE | | Post: 257 Post: 246 | Registrato il: 02/03/2016 Registrato il: 03/03/2016 | Sesso: Maschile | |
|
06/07/2016 10:40 | |
funzioni con passaggio con indirizzi, Indirizzi indipendenti, array delle classi o degli oggetti Dentro una classe è possibile che i suoi membri (le variabili) possano essere dichiarati static ma all’ interno della classe non è possibile allocare la memoria cosi dobbiamo ridefinire la stessa variabile statica all’ esterno della stessa classe basta richiamarla semplicemente, ecco un esempio: class prova { static int statico;int normale;public :void inizializza (int a, int b) {statico = a; normale = b; } void vedi ()} ; int prova::statico; Ora la variabile statica statico è stata veramente creata e come si vede è stata creata (questa variabile) in ambito globale (fuori dalla classe) e ora è veramente una variabile statica èfunzionale, fare attenzione per richiamarla si è dovuto usare l’ operatore di campo o di scope :: per assimilare che appartiene alla classe prova quando si richiama un oggetto di una classe prima di aver creato il nuovo nome di riferimento della classe prova oggetto x ( prova x; x.statico ) tutto quello che è dichiarato dentro la classe va richiamato con lo scope:: esempio per richiamare la funzione vedi(); senza usare l’ oggetto x. si chiama nome_classe ::nome_oggetto ovvero prova::vedi () Come già visto una variabile statica deve ricordare i vecchi dati già passati in modo da totalizzare il nuovo risultato con il vecchio risultato E’ possibile utilizzare anche le funzioni static da dentro una classe ma questa ha delle limitazioni possono accettare solo membri static della classe , non è possibile utilizzare il puntatore this non è possibile dichiarare 2 funzioni uguali tra cui una static l’altra no , inoltre una funzione membro statica non può essere dichiarata costante (const) oppure volatile e non può essere virtuale ma può utilizzare tutte le funzioni o dati globali Poco prima abbiamo parlato del operatore :: abbiamo detto che serve per collegare il nome dell’ oggetto con il nome della classe ovvero lvalue :: rvalue questo operatore che è l’ operatore di scope o meglio operatore del campo d’azione può farci rilevare o accedere anche quei dati variabili globali , se abbiamo 2 variabili di stesso nome una nel campo globale l’altra dentro un gruppo{} e dobbiamo accedere alla variabile globale basta inserire :: lo scope e ecco che richiamiamo la variabile globale Ora parliamo seguendo la lettura del mio libro ancora dei puntatori e array ma per gli oggetti ,come visto gli oggetti sono l’ identificazione delle strutture il nome della struttura cambia in quel nome come esempio sotto il main (mia_classe_nome x) dove x è l’ oggetto questo oggetto possiamo assegnargli sia l’ array oppure il puntatore per farlo diventare un array basta scrivere il nome della classe o l’ oggetto e il numero di elementi che compone l’ array dentro [] : classe o[5] ;Ora la classe è legata alla struttura o[5] è un array da 5 posizioni e o[5] si usa come un normale array ma con dietro collegata tutta la struttura come era con il C e le sue (struct) strutture (quelle strutture non le abbiamo viste da vicino perché sono come queste ma queste sono diverse) per inizializzare questo array di un oggetto si fa come un normale array classe o[2] = {classe(3), classe(15)}; oppure più semplice : classe o[5]={3,15,4,12,901}; sempre dentro le graffe con la classe che legge dentro una funzione ecco un esempio con un solo argomentooggetto x :#include<iostream> using namespace std; class classe{ int x;public: classe (int a) { x=a;} // costruttore e funzione in line int scrivi_x () {return x;} };
int main () { classe o[3] = {classe(12),classe(2),classe(7)}; int c; for (c=0; c < 3; c++) cout << o.scrivi_x() <<endl ; system(“pause”);}invece se abbiamo più argomenti si inserisce l’ altri argomenti o oggetti x e z eccoun esempio inseriamo tutto quello è in grigio :#include<iostream> using namespace std; class classe{ int x, z;public: classe (int a, int b) { x=a; z=b } // costruttore e funzione in line con 2 parametri int scrivi_x () {return x;} int scrivi_z {return z;} }; int main () { classe o[3] = {classe(12,2),classe(5,7), classe(32,33)}; int c; for (c=0; c < 3; c++) cout << o.scrivi_x()<<” , “ <<o.scrivi_z() <<endl; system(“pause”);}Per creare un array legato all’ oggetto o[3] della classe (anzi che legato alla classe come su nell’ esempio ), bisogna inizializzare, in una funzione del costruttore, il membro o i membri della classe, (per inizializzare un membro o una variabile basta scrivere ( a= 0;) sia esso unasemplice variabile o che sia un membro di una classe) dentro una classe lo si fa dentro il costruttore della classe stessa anche in forma inline classe() {a=0;} ora vediamo cosa cambia dall’ primo esempio fatto su solo dentro la classe e l’ uso degli oggetti …cambio in grigiole modifiche ora abbiamo o1 e o2 oggetti array uno o1 inizializzato l’ altro no :class classe{ int x;public: classe (){x=0;} classe (int a) { x=a;} // costruttori e funzioni in line int scrivi_x () {return x;} }; int main () { classe o1[3] = {12,2,7}; classe o2[4]; Con l’ array ad oggetti ora vediamo i puntatori ad oggetti e come i puntatori normali si usa per accedere a questi l’operatore (->)anzi che l’operatore punto ( . ) . Anche qui si usa l’ aritmetica dei puntatori e come i semplici puntatori accede al prossimo elemento dell’ array anche se il puntatore punta verso l’ oggetto della classe oppure è possibile usare un puntatore normale per poi fargli leggere l’ indirizzo dell’ oggetto specificato l’ importante è che il puntatore è dello stesso tipo dell’ oggetto o membro della classe in uso ecco come usare per leggere un membro dall’ esempio su dobbiamo leggere il membro ( int x; ) dichiariamo un semplice puntatore ( int *px; ) ora per accedere al membro ( px = &o1.x; ) sia il puntatore che la variabile sono di uguale tipo entrambi interi ricordiamo che il C++ è molto tipicizzato e assegnamenti di diversi tipi tra puntatore int e puntatore float come faceva il C non li fa anche se si usa il casting perché il C++ verifica che non ci siano delle violazioni per trovare errori in questo caso il compilatore da errore Anche con le classi e i loro oggetti è possibile usare il puntatore nascosto this lo usa direttamente il compilatore per noi utilizzarlo o meno è solo una perdita di tempo il compilatore capisce che scrivere (return this -> x ; ) o ( return x; ) il compilatore C++ legge e assimila ugualmente che è la stessa cosa per il puntatore this si deve sapere che lefunzioni static non usa il puntatore this e alle funzioni friend non viene passato alcun puntatore this perché non sono membri delle classi Un nuovo tipo di puntatore che si usa pochissimo è il puntatore ai membri della classe un puntatore a membro non è un comune puntatore e non è possibile usare i soliti operatoripunto e freccia ( . -> ) , per accedere al membro della classe si deve usare l’ operatore punto e freccia accompagnati dall’ asterisco ( .* ->* ) poi bisogna creare i membri della classe che possono essere benissimo sia funzioni che variabili ,usando il risolutore di campo con l’ asterisco ( ::* ) (tipo è il tipo di dato int float ecc… il nome è il nome che daremo al nuovo membro creato ) puntatore a membro per i dati o variabili: tipo nome_classe ::* nome ; (questo sarà il nome legato al membro delle variabili delle classi ovvero (dati ) )il puntatore membro per le funzioni delle classi, vedere tutto è racchiuso con le parentesi :tipo (nome_classe ::* nome )();poi questi nomi saranno legati al membro dati (variabile ) o funzioni della classe riporto un programma tipo ( puntatori a membri.txt ) vedete i commenti dentro il file aprite un nuovoprogetto aprite un nuovo file poi copiate il mio txt e lo salvate in .cppSi è parlato già di puntatori e indirizzi , per leggere un indirizzo si usa la e commerciale ( & ) mentre per far puntare un puntatore si usa l’ asterisco ( * ) ora vediamo meglio l’ indirizzo di memoria che può essere usato da solo per leggere la posizione di memoria di una variabile, oppure è possibile usarlo per essere un parametro per indirizzo o un valore per le funzioniIl parametro per indirizzo manuale si genera impiegando un puntatore, mentre usando la & la chiamata all’ indirizzo di memoria è fatta in automatico senza usare più i puntatori nelle funzioni ovvero in modo manuale come potete vedere nell’ esempio che allego e potete copiare vedete i 3 diversi esempi il primo usa la chiamata manuale con i puntatori funzione mentre la funzione2 e 3 usa la chiamata diretta tramite l’ operatore ( & ) vedi il mio programma (chiamata perindirizzo.txt ) Ora abbiamo visto che i parametri delle funzioni sono passati come indirizzi, ma non solo i parametri possono passare alle funzioni , le funzioni può restituire indirizzi tramite lvalue e nonsolo rvalue una cosa importante , quando si restituisce l’ indirizzo bisogna fare attenzione che non si esca dal campo della visibilità di cui l’ oggetto fa riferimento alla fine della funzioneGli indirizzi indipendenti che è un nome diverso per una variabile in cui leggiamo il suo indirizzo tramite ( & ) andiamo a creare una variabile normale int var ; ora int &vv = var ; questa nuova variabile vv è l’ indirizzo indipendente che affianca o meglio legge all’ indirizzo della variabile var ora quello che noi facciamo sulle due variabili var = 10; oppure vv = 11; noitroviamo in entrambe le variabili il nuovo valore ugualmente se appoggiamo vv su una nuovavariabile var2 = 13 ; vv=var2 ; ecco che var porta il valore di var2 ovvero se leggiamo cout << var ; il valore sarà 13 come abbiamo assegnato a vv = var2; L’ uso degli indirizzi su una classe base può essere utilizzato come riferimenti sia su classi base che classi derivate i parametri d’indirizzo possono essere usati nei oggetti sia della classe base che da quella derivata Restrizioni agli indirizzi non è possibile creare l’ indirizzo di un indirizzo , non si può creare l’ array di indirizzi come non si può creare un puntatore a un indirizzo , non si può conoscere l’ indirizzi dei campi di bit , non si può usare l’ indirizzi nulli, la variabile indirizzo deve essere inizializzata al momento della dichiarazione tranne se è un membro di una classe o il parametro di una funzione sia esso un valore da restituire che i parametri Solo quando si usa i puntatori si utilizza l’ operatore freccia ( -> ) per accedere ai membri della classe , se si usa il passaggio dei parametri per indirizzo si usa l’ operatore punto ( .) per accedere dentro i membri della classe associare l’ operatore ( * o & ) al tipo o alla variabile per il compilatore è sempre uguale scrivere int* p; o int *p; il compilatore assimila che int p è un puntatore dichiarare più variabili inserendo il puntatore int * a, b; in questo modo solo a è un puntatore mentre b è solo una normale variabile ugualmente se si usa la & int & a,b; solo a legge l’indirizzo della cellula di memoria , mentre b rimane una semplice variabileintera Ciao grazie da ByMpt-Zorobabele Testo PDF aggiornato con questo ultimo capitolo inserito lo trovate:http://www.freeforumzone.com/d/11266858/Elenco-figure-dei-comandi-della-programmazione-C-TESTO-PDF/discussione.aspxAnche qui di queste discussioni che inserisco faccio un testo PDF da poterscaricare tutto il mio materiale è da utilizzare come desiderate per il testo PDF vedi cartella dedicata , ogni volta cambia ubicazione del testo allora cambio il file e il testo lo inserisco dentro la cartella < file aggiornato ad oggi >http://www.freeforumzone.com/d/11266858/Elenco-figure-dei-comandi-della-programmazione-C-TESTO-PDF/discussione.aspx [Modificato da JehovaZorobabele 21/07/2016 14:09] |