Newsgroup: it.comp.lang.c++
Titolo: membri di una classe. Domanda.

ciao a tutti,
premesso che sono un principiante, vi faccio una domanda:
in una funzione membro di una classe e` possibile che i parametri
formali della chiamata di funzione siano gli attributi della classe
stessa o devo per forza usare delle variabili temporanee ?
Mi spiego meglio, se ho una classe FaQualcosa cosi` definita:
class FaQualcosa
{
    public:
        int funzioncina (long);
    private:
        long value;
}
il metodo funzioncina cosi definito e` corretto ?
int FaQualcosa::funzioncina(value)
{
    value += 10;
    return value;
}
o devo definire funzioncina cosi:
int FaQualcosa::funzioncina(long tempVal)
{
    tmpVal += 10;
    return tmpVal;
}
grazie a tutti.
Bye, Max


No, per accedere ad un campo dati dell'oggetto di invocazione della
funzione devi usare il puntatore this, che si riferisce appunto
all'oggetto di invocazione. Ecco un esempio
int FaQualcosa::funzioncina()
{
    this->value+=10;           
    return this->value;
}
Spero di essere stato chiaro, comunque ti consiglio di consultare un
buon manuale, che sicuramente spiega il tutto in modo più chiaro e
dettagliato.
Ciao,
Alberto Griggio


E' sbagliato.
l'utilizzo del puntatore this e' implicito nelle funzioni membro non
static.
--
Ivan Molella
__LINUX__ the choice of the __GNU__ generation
icq# 97960484

 }
Cosi' va bene:
int FaQualcosa::funzioncina()
{
    value += 10;
    return value;
}



Hai ragione, è completamente inutile. Mi scuso per la svista, non so
perché l'ho scritto... 
Alberto Griggio
P.S.: Comunque non è sbagliato in senso stretto (non da nessun errore
o warning), anche se una cosa non necessaria di solito è meglio non
scriverla

static.
Forse Alberto intendeva:
  int FaQualcosa::funzioncina(int value)
  {
    this->value+=value;
    return this->value;
  }
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

 }
Ok, vi ringrazio tutti per le risposte, ma forse sono stato io poco
chiaro.
Ci provo ...
Il valore da assegnare all'attributo della classe viene passato al
metodo come parametro. Ora mi chiedo se nella definizione della funzione
posso scrivere come parametro della funzione direttamente l'attributo
della classe.
Insomma:
class FaQualcosa
{
    private:
        int value;
    public:
        void FaQualcosa::funzioncina(int);
}
int FaQualcosa::funzioncina(value)
{}     // Il metodo assegna all'attributo value il valore passato come
parametro ?
piuttosto che definerla come
void FaQualcosa::funzioncina (int tmpValue)
{    value = tmpValue; }   // E quindi fare uso di una variabile
temporanea per l'assegnamento
Ci ho provato ...
Bye, Max


Si,In questo caso l'utilizzo di this e' necessario,anche se io
personalmente preferisco evitare dichiarare nomi,che ne ricoprano altri,
nel campo di visibilta' corrente.


 temporanea per l'assegnamento
Questa invece si.
Secondo me stai confondendo la sintassi che si usa per
l'inizializzazione dei membri dati nei costruttori, con la sintassi di
funzioni membro normali
Se in FaQualcosa tu avessi un costruttore dichiarato:
class FaQualcosa {
  public:
    FaQualcosa(int);
// ...
  private:
    int value;
};
Potresti poi definirlo come:
FaQualcosa::FaQualcosa(int v) : value(v) {}
per ottenere che v sia assegnato a value. Per le funzioni membro normali
una sintassi del genere non esiste e devi utilizzare quella del tuo
secondo esempio.
Ciao,
Nicola


Ho visto spesso codice di questo genere in giro, ma lo ritengo inutilmente
rischioso.
Ciao
Domenico Barra

static.
Il fatto che sia inutile usare this in questo caso non vuole affatto
dire che sia sbagliato. C'é chi preferisce usarlo sempre per motivi di
chiarezza, anche se effettivamente io non lo uso.
Il Ghenio
-----
E'più oscuro del crepuscolo, é più rosso del sangue,
in nome della pace e della giustizia faccio appello a
tutti i poteri più remoti dell'oscurità, perché mi
aiutino a distruggere i miei nemici e tutti coloro
che saranno tanto sciocchi da ostacolarmi. FULMINE ROSSO!!
(Slayers)
-----

  }
Se proprio la gente vuol farsi del male.... Io non userei mai un
parametro con lo stesso nome del dato membro. Piuttosto qualcosa del
tipo
int FaQualcosa::funzioncina(int _value)
{
    value += _value;
    return value;
}
L'uso del puntatore this può essere facilmente evitato a mio avviso.


temporanea per l'assegnamento
Utilizzando il passaggio di parametri per valore effettivamente viene
fatta una copia temporanea della variabile che é stata passata, il che
é ben poca cosa se si tratta di dati primitivi, ma può appesantire
notevolmente il lavoro del compilatore quando ad essere passati sono
degli oggetti o delle strutture dati molto grosse. Il tutto può essere
risolto utilizzando il passaggio di parametri per indirizzo:
void FaQualcosa::funzioncina (int &tmpValue)
oppure, se vuoi che la variabile passata per indirizzo non possa
essere modificata...
void FaQualcosa::funzioncina (const int *tmpValue)
Arrivederci...


L'uso del puntatore this può essere facilmente evitato a mio avviso.
Un sistema abbastanza diffuso in C++ e' quello di chiamare
sempre *tutti* i membri di una classe con nomi che finiscono
con "_" in modo da avere a disposizione il nome "pulito" per
i parametri:
  class Point
  {
    private:
      double x_,y_;
      int color_;
    public:
      Point(double x,double y,int color)
      : x_(x),y_(y),color_(color)
      { }
    ...
  };
HTH


void FaQualcosa::funzioncina (const int *tmpValue)
Un metodo molto usato (specie nei template in cui
non si conosce quanto sara' grande l'oggetto gestito)
e' quello di usare un const reference:
  template<class T>
  class FaQualcosa
  {
    ...
    void funzioncina(const T& value)


 chiarezza, anche se effettivamente io non lo uso.
Attenzione che c'e' una piccola perdita di prestazioni, perche' al
compilatore non e' consentito eliminare la dereferenziazione di this se
e' espressa esplicitamente (ragionevole, no? visto che in genere e'
assolutamente inutile, se qualcuno la scrive ci sara' un motivo...).
Inoltre trovo discutibile adottare una convenzione personale diversa da
quella di *tutti* gli altri programmatori C++.
Ciao,
Nicola

 
Salve a tutti, scusate ma mi sembra doverosa una precisazione, visto il
piccolo dibattito che si e' acceso: non intendevo fare nulla di
esoterico o di potenzialmente pericoloso con questa funzione.
semplicemente credevo che usando il this esplicitamente le cose
risultassro piu' chiare.
Evidentemente il mio tentativo ha dato esiti opposti: scusatemi.
Alberto Griggio

 
Non capisco.
Se parli di perdita di prestazioni, vuol dire che il compilatore potrebbe
o dovrebbe, nei due casi, generare codice diverso. 
Ora, non mi è chiaro quali differenze potrebbero esserci, giacchè non mi
pare si possa prescindere dal valore che this assume di volta in volta
visto che si deve comunque utilizzarlo come argomento implicito nella
chiamata dei metodi o come meccanismo per la risoluzione di eventuali
chiamate a metodi virtual.
Cosa mi sfugge? 
Max

 int FaQualcosa::funzioncina(int _value)
Meglio
int FaQualcosa::funzioncina(int value_)
dato che i nomi che iniziano con l'underscore sono riservati.
EMG

>all'oggetto di invocazione. Ecco un esempio
che specifica "il dovere" di usare il puntatore this esplicitamente per
accedre ad un membro dell'oggetto,mentre cio' non e' vero


nomi riservati e possono realmente creare problemi.
Ok, accuso il colpo. Comunque io non ho mai avuto problemi, anche
perché solitamente uso nomi di variabili scritti in italiano.


scriverla
ci sono dei casi in cui è indispensabile, ad esempio certe situazioni
in un template derivato da un'altro template.

 dato che i nomi che iniziano con l'underscore sono riservati.
Mi pare però che siano riservati soltanto i nomi che iniziano con un
doppio underscore o con un underscore seguito da una lettera maiuscola. 
Mi sbaglio?
Max

 Mi sbaglio?
Boh, mi ricordavo diversamente ma può darsi che tu abbia ragione.
EMG

    value += 10;
modifichi il parametro attuale, non l'attributo.
Per modificare l'attributo devi utilizzare necessariamente this.
Paolo

 doppio underscore o con un underscore seguito da una lettera maiuscola.
Anche tutti quelli che contengono un doppio underscore (non
necessariamente all'inizio).
	Mauro

       int color_;
Io mi affiderei piu' che altro ai ben noti :
class Pippo
{
private:
    int m_myint;
    void MyFunc(int p_myvalue)
...
Ma i giochetti con _ li lascerei perdere pure io :)