Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C++] Un problema di namespace

    Buongiorno!
    Ho due classi, chiamiamole rispettivamente A e B in una situazione in cui A utilizza al suo interno B. Il problema è che sia A che B hanno un metodo con lo stesso nome, e questo mi crea dei casini assurdi in fase di linking (compilazione invece tutto ok).
    Riporto l'esempio concreto, con le classi Button e Image:

    codice:
    class Button
    {
    private:
    	Image img( [definizione del costruttore] );
    	
    public:
    	Button( Image img )
    	{
    		this->img = img;
    	}
    	
    	void draw( void )
    	{
    		this->img.draw();
    	}
    };
    Pensate sia lecito tutto questo? Ottengo prima un errore nel passaggio
    codice:
    this->img = img
    all'interno del costruttore ( invalid use of member (did you forget the ‘&’ ?)), e poi con il metodo Button::draw (‘((Button*)this)->Button::img’ does not have class type). Devo crearmi dei namespace personalizzati?
    Vi ringrazio in anticipo per qualsiasi indizio positivo!

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Il namespace non centra niente (almeno vedendo quel codice).
    A me sembra proprio un errore di compilazione, non di linking.
    La classe Image com'è definita?
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3
    Ciao shodan, per questo progetto sto usando SDL (la libreria dedicata alla gestione audio/video, in generale per lo sviluppo di applicazioni multimediali o videogiochi), quindi il costruttore di Image prevede oggetti di quella libreria:

    codice:
     Image m( const char *imgFile, SDL_Surface *dest )
    Il file che ho riportato prima è Button.cpp e lo importo direttamente nel main, dove tra le varie cose creo un oggetto Image e lo passo al costruttore di Button.

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381

    Re: [C++] Un problema di namespace

    Il problema dovrebbe essere questa riga (che mi era sfuggita prima):
    codice:
    class Button
    {
    private:
    	Image img( [definizione del costruttore] ); 
    public:
    	Button( Image img )
    	{
    		this->img = img;
    	}
    	
    	void draw( void )
    	{
    		this->img.draw();
    	}
    };
    Non è possibile inizializzare un oggetto in quel modo all'interno di una classe.
    O risolvi utilizzando la constructor list initializer (è necessario che la classe abbia il costruttore di default)
    codice:
    Button( [parametri da passare al costruttore di image ] ) : img([parametri da passare al costruttore di image ]
    	{ }
    oppure sei costretto a usare un puntatore (meglio uno smart pointer)
    codice:
    class Button
    {
    private:
    	Image* img;
    
    Button( Image im ) : img (new Image) {
       *this->img = im;
    }
    etc...
    La classe Image l'hai scritta tu immagino (nella doc di SDL qui: http://jcatki.no-ip.org:8080/SDL_ima...age_frame.html non vedo classi)
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    Sì, la classe Image l'ho costruita io per fare questa prova della classe dentro la classe.

    Comunque devo dire che il link sulle FAQ C++ che hai in firma era proprio quello che mi serviva
    Partendo dai tuoi due suggerimenti, ho capito che utilizzi la constructor list initializer in entrambe le soluzioni, ma cambiando i parametri: come mai?

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Nel primo esempio uso la list per inizializzare l'oggetto img (tra l'altro non serve che la classe abbia un construttore di default: quella sintassi lo bypassa), nel secondo alloco il puntatore e poi copio l'oggetto in questione.
    Il secondo caso è quello più rognoso, in quanto occorre gestire il puntatore; non tanto nella futura deallocazione, ma in caso di copia o assegnamento di un oggetto di classe Button (per quello suggerisco sempre smart pointer).
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  7. #7
    Fantastico, credo di esserci, ma mi sfugge un dettaglio: tralasciando la seconda ipotesi puntatore, la prima mi pare che sia utile nel caso voglia costruire un Image dentro Button, dico bene? Io invece vorrei fare in modo che la classe Button gestisca un oggetto Image istanziato all'esterno...

  8. #8
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Se dichiari una variabile private del tipo Image img in ogni caso lavori su una copia.
    Se vuoi lavorare direttamente su un oggetto esterno hai due possibilità:
    1) passi un puntatore;
    2) passi un reference;

    In ambedue i casi, il lifetime dell'oggetto Image dev'essere superiore a quello dell'oggetto Button o il programma s'inceppa.
    Fai un esempio di come vorresti fare.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  9. #9
    E' vero, diciamo che per ottimizzare sarebbe meglio un puntatore ( o un reference ).
    A parte questo, ti incollo un esempio in codice php-style di quello che vorrei fare:

    codice:
    class Button
    {
    	private img;
    	
    	Button(img)
    	{
    		this->img = img;	
    	}
    	
    	draw()
    	{
    		this->img->draw();
    	}
    }
    Dove "img" è un oggetto già istanziato, fuori da Button (per esempio nel main); il metodo draw() di Button richiama draw() dell'oggetto img.

    Ne approfitto per ringraziarti perchè mi stai passando molti concetti nuovi di c++ che non conoscevo (su tutti la constructor list initializer)!

  10. #10
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Il punto non è ottimizzare, ma fare attenzione perché il programma non vada in tilt.
    Ad esempio:
    codice:
    Image* img = new Image(...);
    Button btn(img); // passo il puntatore ad un oggetto nell'heap. 
    //Dove lo libero? Nel distruttore di Button o in seguito? 
    
    Image img_a(...);
    Button btn_a(&img_a); // passo il puntatore di un oggetto sullo stack. 
    // Non posso fare una delete di un oggetto posto sullo stack. 
    
    Image* img_a = new Image(...);
    Button btn_b(*img_b); // passo il reference.  
    delete img_b;
    // il reference di btn_b adesso è invalido.
    Sono esempi un pò forzati, ma dovrebbero rendere l'idea di che succede se non si fà attenzione al lifetime dell'oggetto considerato.

    Invece:

    codice:
    Image* img = new Image(...);
    Button btn(img); // passo il puntatore ad un oggetto nell'heap, 
    ma non lo libero nel distruttore: ci devo pensare fuori.  
    
    Image img_a(...);
    Button btn_a(&img_a); // passo il puntatore di un oggetto sullo stack. 
    
    Image img_b(...)
    Button btn(img_b); // passo un reference. 
    //L'oggetto img_b ha lifetime superiore rispetto a btn, quindi sono sicuro.
    Vanno bene.
    In caso tu voglia utilizzare un reference, la sintassi della classe diventa:
    codice:
    class Button
    {
    private:
    	Image& img; 
    public:
    	Button(Image& i ) : img(i) // obbligatorio
    	{ }
    	
    	void draw( void )
    	{
    		img.draw();
    	}
    };
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.