Results 1 to 11 of 11

Thread: Help C++ Return Reference

  1. #1
    Ensign Hardcore's Avatar
    Join Date
    Sep 2006
    Location
    Modena
    Posts
    3.550

    Default Help C++ Return Reference

    Per un qualche motivo misterioso, all'ultimo anno di ing han deciso che è vitale che sappia il c++, ergo arrivando da 4 anni di Java è una menata.

    C'è una cosa che mi rimane ancora misteriosa ed è il concetto di reference, soprattutto quando è nel return value.

    Code:
    template <typename _T> class image{
    
    	unsigned    _w,_h;
    	vector <_T> _pixels;
         public:
    image (unsigned w=0,unsigned h=0) :_w(w),_h(h),_pixels(_w*_h){}
    
    _T& operator () (unsigned x,unsigned y) {
    
    		return _pixels[(y*(_w-1)+x)-1];
    	}
    Nel mio es il _T è un unsigned char, ergo quando faccio _pixels[blabla] ottengo un valore specifico di un unsigned char, ma cosa diavolo vuol dire che ritorno _T&, non mi è chiaro il &...

    __________________________________________________ _________________

    Altra cosa non chiara:
    Code:
    const _T& operator ()(unsigned x,unsigned y) const {
    Per quale motivo ci sono due const?
    Last edited by Hardcore; 11th May 2011 at 10:12.


  2. #2
    Lieutenant Commander San Vegeta's Avatar
    Join Date
    Oct 2003
    Location
    Bologna
    Posts
    12.154

    Default

    se non ricordo male, il reference è un puntatore a una locazione di memoria.
    restituire un reference a un valore significa che chi si salva quel valore nella variabile ref_a, ha un puntatore alla locazione di memoria dove è salvato il valore: ogni modifica a quel valore si riflette nella variabile ref_a.
    Edit: dimenticavo che il reference, una volta inizializzato, non puo' essere riassegnato: questa caratteristica, insieme al fatto che viene utilizzato come una normale variabile, lo rende differente dai puntatori

    il secondo quesito non me lo ricordo, sorry
    I rubinetti a casa di Chuck Norris non perdono, vincono.

    In the beginning there was nothing...then Chuck Norris Roundhouse kicked that nothing in the face and said "Get a job". That is the story of the universe.

    Quote Originally Posted by Wolfo View Post
    Concordo e propongo ban temporanei per chi critica la topa , la topa non si critica , dal trombabile in su non si commenta in modo sgradevole.
    la tua ignoranza in materia e' raccapricciante
    -cit. Estrema, 2022

  3. #3
    Master Chief Petty Officer Dr.Doomed's Avatar
    Join Date
    Jul 2005
    Location
    Latveria
    Posts
    2.067

    Default

    Quote Originally Posted by Hardcore View Post
    ...
    __________________________________________________ _________________

    Altra cosa non chiara:
    Code:
    const _T& operator ()(unsigned x,unsigned y) const {
    Per quale motivo ci sono due const?
    Il primo const si riferisce al valore ritornato, di fatto dicendoti che ritorna un valore costante che non puo` essere modificato, mentre il secondo const si riferisce alla funzione e serve per evidenziare come la funzione non puo` modificare i valori delle variabili di classe.
    http://duramecho.com/ComputerInforma...wCppConst.html
    Le masse saranno sempre al di sotto della media. La maggiore età si abbasserà, la barriera del sesso cadrà, e la democrazia arriverà all'assurdo rimettendo la decisione intorno alle cose più grandi ai più incapaci.
    Sarà la punizione del suo principio astratto dell'uguaglianza, che dispensa l'ignorante di istruirsi, l'imbecille di giudicarsi, il bambino di essere uomo e il delinquente di correggersi. Il diritto pubblico fondato sulla uguaglianza andrà in pezzi a causa delle sue conseguenze.
    Perché non riconosce la disuguaglianza di valore, di merito, di esperienza, cioè la fatica individuale: culminerà nel trionfo della feccia e dell'appiattimento. L'adorazione delle apparenze si paga.
    "Frammenti di diario intimo", 12 giugno 1871

    They are entitled to their opinion but they suffer from the notable disadvantage of being completely wrong

    Discutere con certe persone è come giocare a scacchi con un piccione. Puoi essere anche il campione del mondo ma il piccione farà cadere tutti i pezzi, cagherà sulla scacchiera e poi se ne andrà camminando impettito come se avesse vinto lui.

    ~-~-~ νῦν μὴ κακά στοχάζομαι ~-~-~

  4. #4
    Ensign Hardcore's Avatar
    Join Date
    Sep 2006
    Location
    Modena
    Posts
    3.550

    Default

    Quote Originally Posted by San Vegeta View Post
    se non ricordo male, il reference è un puntatore a una locazione di memoria.
    restituire un reference a un valore significa che chi si salva quel valore nella variabile ref_a, ha un puntatore alla locazione di memoria dove è salvato il valore: ogni modifica a quel valore si riflette nella variabile ref_a.
    Edit: dimenticavo che il reference, una volta inizializzato, non puo' essere riassegnato: questa caratteristica, insieme al fatto che viene utilizzato come una normale variabile, lo rende differente dai puntatori

    il secondo quesito non me lo ricordo, sorry
    ok, ma quindi se mettiamo che io volessi poter accedere a tale valore dalla funzione main, devo usare una variabile puntatore?

    cioè se faccio:

    Code:
    class prova{
    
    int _a;
    
    public:
    
    prova(): _a(0){}
    
    int & get_a(){
    
    return a;
    }
    
    };
    
    void main(){
    
    prova test;
    
    int* a1=test.get_a(); 
    
    int a2=test.get_a();
    
    }
    se lavoro con a1 modifico a della classe, mentre se lavoro con a2, vado a modificarne una copia con scope solo nel main? ho capito bene?


  5. #5
    Lieutenant Commander San Vegeta's Avatar
    Join Date
    Oct 2003
    Location
    Bologna
    Posts
    12.154

    Default

    non devi usare un puntatore, devi usare un reference.

    se non erro la sintassi è

    ref int a = test.get_a();
    I rubinetti a casa di Chuck Norris non perdono, vincono.

    In the beginning there was nothing...then Chuck Norris Roundhouse kicked that nothing in the face and said "Get a job". That is the story of the universe.

    Quote Originally Posted by Wolfo View Post
    Concordo e propongo ban temporanei per chi critica la topa , la topa non si critica , dal trombabile in su non si commenta in modo sgradevole.
    la tua ignoranza in materia e' raccapricciante
    -cit. Estrema, 2022

  6. #6
    Warrant Officer marlborojack's Avatar
    Join Date
    Mar 2009
    Location
    Pisa
    Posts
    3.215

    Default

    Code:
    template <typename _T> class image{
    
    	unsigned    _w,_h;
    	vector <_T> _pixels;
         public:
    image (unsigned w=0,unsigned h=0) :_w(w),_h(h),_pixels(_w*_h){}
    
    _T& operator () (unsigned x,unsigned y) {
    
    		return _pixels[(y*(_w-1)+x)-1];
    	}
    [/QUOTE]

    Ridefinendo un operatore devi ritornare un valore sinistro, perchè l'operatore in pratica viene chiamato sull'oggetto this della classe come parametro formale. In questo modo quello che viene chiamata è l'istanza dell'oggetto this e viene ritornato l'oggeto stesso modificato. Se tu non usassi un riferimento &, ritorneresti una copia dell'oggetto this, ovvero una nuova istanza senza modificare l'oggetto sul quale chiami il metodo.
    __________________________________________________ _________________

    Altra cosa non chiara:
    Code:
    const _T& operator ()(unsigned x,unsigned y) const {
    Per quale motivo ci sono due const?
    ritorna un riferimento costante (primo const), perchè il metodo ritorna this come oggetto non modificabile, ovvero come riferimento costante. Il metodo in sè stesso poi è costante, nel senso che ritorna un'instanza costante. Se così non fosse, paradossalmente potresti scrivere qualcosa tipo
    (a + b) (normalmente un valore destro, per i tipi base, quindi non assegnabile a sinistra) = c (assegnare un valore destro a quello che dovrebbe essere un valore destro ma in realtà lo rendi un valore sinistro senza il secondo const), ovvero assegnare al riferimento a this ritornato dal template un nuovo valore mandando un vacca l'organizzazione ad oggetti.

    Se questi concetti non ti sono chiari però ti consiglio di dare una lettura allo Stroustrup, altrimenti chiedi pure
    Happiness in intelligent people is the rarest thing I know.

  7. #7
    Lieutenant Junior Grade Eltarion's Avatar
    Join Date
    Dec 2004
    Location
    Venaria
    Posts
    4.085

    Default

    arrivo in ritardo ma quoto marlboro :P
    Realm Of Trollers
    while ( ! ( succeed = try() ) );
    Spoiler

  8. #8
    Warrant Officer marlborojack's Avatar
    Join Date
    Mar 2009
    Location
    Pisa
    Posts
    3.215

    Default

    :P

    Comunque questo esempio è un casino, perchè la sintassi è complicata dal template. Cerco di spiegarmi meglio:

    Con i template definisci oggeti che non dipendono dalla rappresentazione, nel caso specifico l'immagine, per memorizzata che sia, deve essere istanziata con le proprietà di altezza e lunghezza. Il template serve a farti eseguire le operazioni definendo in seguito la rappresentazione, nel tuo caso un tipo_pixels mi pare di capire, che sarà a occhio un array di pixels, che da solo non manterrebbe l'informazioni senza imporre l'interfaccia data dal template.

    Quando dichiari un oggetto Image in questo caso metti tra le angolate l'oggetto al quale l'interfaccia, in questo modo a tempo di esecuzione istanzi dei metodi su di un certo tipo e nel contempo a livello di scrittura del codice puoi utilizzare i metodi. Di più, in C++ puoi definire i tipi ma soprattutto ridefinire gli operatori, che sono costrutti più complessi perchè sono binari: è previsto infatti un operando sinistro ed un operando destro.

    Gli operatori dei tipi base devono eseguire il risultato dell'operazione e ritornare il valore destro; per scriverlo in c++, si dice

    funzione che ritorna iun oggetto del tipo definito come valore destro (ovvero un'area di memoria non modificabile che può essere assegnata ad un valore sinistro)

    Code:
    const _T&
    col & gli dici di ritornare un'area di memoria già instanziata (il risultato della chiamata del costruttore), con _T gli dichiari il tipo da ritornare e con const imponi che non sia modificabile il riferimento in sè (ovvero se in qualche chiamata cerco di modificarlo ottengo un errore di compilazione), ma devi anche esprimere il fatto che l'oggetto in sè non è modificabile. da cui il secondo const che indica che l'oggetto in sè non può essere modificato. Infatti, non è possibile chiamare i metodi di un valore destro. Quindi

    funzione che ritorna un oggetto del tipo definito come valore destro (ovvero un'area di memoria non modificabile che può essere assegnata ad un valore sinistro)

    Code:
    const _T& () const {
    in sostanza

    La classe immagine opera su un tipo generico
    Code:
    template <typename _T> class image{
    memorizza due interi con lunghezza e altezza
    Code:
    	unsigned    _w,_h;
    ma i pixel possono essere rappresentati da un oggetto generico.
    L'immagine è comunque un vettore di questi pixels
    Code:
    	vector <_T> _pixels;
    Costruisco un'immagine con una lista d'inizializzazione, ovvero chiamando i costruttori propri dei membri
    Code:
         public:
    image (unsigned w=0,unsigned h=0) :_w(w),_h(h),_pixels(_w*_h){}
    Faccio in modo che se chiamo immagine(x,y) mi sia ritornato il pixel corrispondente
    ritornando il tipo generico (templetizzato) alla posizione interna del vettore. La rappresentazione interna dell'immagine è un vettore di righe * colonne pixels, ritorno quello
    alla posizione bidimensionale x, y;
    Code:
    _T& operator () (unsigned x,unsigned y) {
    
    		return _pixels[(y*(_w-1)+x)-1];
    	}
    Il pixel non lo posso modificare, così come non posso scrivere immagine(x,y) = c (errore a tempo di compilazione)
    Happiness in intelligent people is the rarest thing I know.

  9. #9
    Lieutenant Junior Grade Eltarion's Avatar
    Join Date
    Dec 2004
    Location
    Venaria
    Posts
    4.085

    Default

    adesso però te la stai tirando eh!!

    scherzo, ottima spiegazione
    Realm Of Trollers
    while ( ! ( succeed = try() ) );
    Spoiler

  10. #10
    Ensign Hardcore's Avatar
    Join Date
    Sep 2006
    Location
    Modena
    Posts
    3.550

    Default

    Quote Originally Posted by marlborojack View Post
    Code:
    _T& operator () (unsigned x,unsigned y) {
    return _pixels[(y*(_w-1)+x)-1];
    }
    Il pixel non lo posso modificare, così come non posso scrivere immagine(x,y) = c (errore a tempo di compilazione)
    In primis grazie per la spiegazione, molto chiara

    Unica cosa che nn ho capito è questa.
    Per quale motivo dici che nn posso modificarlo?
    Qui non ritorna un const,e quindi dovrei poter modificarlo,lo scopo di questa funzione è proprio questo


  11. #11
    Warrant Officer marlborojack's Avatar
    Join Date
    Mar 2009
    Location
    Pisa
    Posts
    3.215

    Default

    Quote Originally Posted by Hardcore View Post
    In primis grazie per la spiegazione, molto chiara

    Unica cosa che nn ho capito è questa.
    Per quale motivo dici che nn posso modificarlo?
    Qui non ritorna un const,e quindi dovrei poter modificarlo,lo scopo di questa funzione è proprio questo
    Pensavo alla seconda richiesta che hai fatto con i const e lì per lì non ho notato che nel codice poi non c'erano comunque penso tu abbia capito, visto che giustamente me l'hai fatto notare.
    Happiness in intelligent people is the rarest thing I know.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
[Output: 90.82 Kb. compressed to 78.12 Kb. by saving 12.70 Kb. (13.98%)]