Newsgroup: it.comp.lang.c++
Titolo: Singleton: Instance() come puntatore o come reference?

Ciao,
guardando una qualsiasi implementazione del singleton si trova sempre qualcosa
di simile a quanto esposto nel 'Design Patterns' della Gang of Fours
[code]
class Singleton {
public:
    static Singleton* Instance();
protected:
    Singleton();
private:
    static Singleton* _instance;
};
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance () {
    if (_instance == 0) {
        _instance = new Singleton;
    }
    return _instance;
}
[/code]
Vorrei sapere se ci sarebbero svantaggi nell'usare
[code]
Singleton& Singleton::Instance () {
    if (_instance == 0) {
        _instance = new Singleton;
    }
    return *_instance;
}
[/code]
Grazie.

 'Design Patterns' della Gang of Fours
Dai un'occhiata a questi articoli, secondo me sono molto validi
http://www.devarticles.com/c/a/Cplusplus/C-plus-plus-In-Theory-The-Singleton-Pattern-Part-I
http://www.devarticles.com/c/a/Cplusplus/C-plus-plus-In-Theory-The-Singleton-Pattern-Part-2/1/
HTH
C:\>iao Angelo

Angelo Paolitto ha scritto:

Molto istruttivo, specie la parte
"An additional safeguard is the returned reference instead of the 
pointer. The caller cannot be tempted to delete the singleton (as was 
the case when we were returning a pointer)."
Grazie.
 
-- Posted on news://
freenews.netfront.net
 - Complaints to 
ne...@netfront.net
 --

 
http://www.devarticles.com/c/a/Cplusplus/C-plus-plus-In-Theory-The-Si.
..
class Singleton {
public:
static Singleton& Instance() {
  static Singleton theSingleton;
  return theSingleton;
}
};
le funzioni definite in questo modo di default sono inline
il problema è che questa funzione non deve essere inline altrimenti ne
esisterebbero più istanze e questo violerebbe il requisito del
Singleton
come posso essere sicuro che il compilatore non la renderà come
inline?
... tutto questo coinvolge aspetti di internal/external linkage per me
tutt'altro che banali
avete qualche informazione definita su questo punto?
ciao,
Marco

 Singleton
E chi l'ha detto che esisterebbero piu' istanze delle variabili statiche 
locali?
Mi risulta che solo il codice viene espanso inline, non le variabili.
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

 Mi risulta che solo il codice viene espanso inline, non le variabili.
era il genere di conferma che mi serviva, grazie
infatti a me non interessa che il codice venga espanso, l'importante è
che esista un unica istanza delle variabili statiche locali
hai per caso anche qualche riferimento, es. allo standard?
Marco

 locali?
'mfatti ...
Ma, a parte la staticità personale della data variabile, se 
uno antepone lo STATIC anche davanti alla dichiarazione 
della funzione stessa, non forza comunque a mano la non 
espansione inline ?
Anzi, mi risulta che quello static anteposto alla 
dichiarazione di funzione, rendendo la stessa chiamabile a 
prescindere da qualsivoglia istanza specifica, come 
NomeClasse::NomeRoutineStatica (...), costringe in realtà a 
fare uso, nel suo codice SOLTANTO di variabili statiche e di 
nessuan variabile membro automatica o dinamica.
Quella funzione è soltanto "in scope" relativamente alla 
classe, ma non è una funzione membro nel senso classico, a 
prescindere dal tipo ritornato .... o sto sbagliando ?
ciao
Soviet_Mario


 forza comunque a mano la non espansione inline ?
Perché mai? Una funzione static può essere espansa inline (ed è molto 
importante che ciò venga fatto!) come una qualunque altra funzione. Ad 
esempio:
extern int x;
inline void incrementa() {
	x++;
}
Per quale motivo temi che la variabile x venga duplicata?
La regola generale è che l'attributo "inline" non deve modificare il 
significato del codice. E' solamente un "hint" al compilatore, come 
poteva essere "register".
Qualche dubbio ci può essere con la duplicazione delle variabili static 
dei template, ma quello è tutto un altro discorso, che non c'entra 
(quasi) niente con l'inline.
E.

 dei template, 
oddio, non l'avevo ma me lo fai venire ora ! Pensavo che 
ogni singola specializzazione templatica avesse la sua 
propria copia delle variabili static, e che non ci fosse 
sovrapposizione.
Forse c'è modo di farlo, ma non so come si possa avere 
un'istanza unica condivisa tra più template (che poi sono 
classi distinte)
ciao
Soviet


 (quasi) niente con l'inline.
in effetti i miei dubbi sono proprio su questo
tempo fa avevo valutato il seguente template
template<class T>
T& Singleton()
{
 static T t;
 return t;
}
(in pratica permette di creare un Meyers Singleton a partire da
qualunque classe)
beh, il mio problema è che non sono sono stato capace di trovare una
garanzia del fatto che la chiamata
 Singleton<MyClass> ()
fatta in cpp diversi, acceda alla stessa e unica istanza statica di
MyClass
M.

 M.
mah, io da sprovveduto ho fatto due files .cpp
[code]
class AClass{
  friend AClass& Singleton();  //solo Singleton puo' istanziare
                               //oggetti AClass
  AClass(){
    storage = new char[1024*1024*50];  //ogni istanza prende 50MB
  }
  char* storage;
};
template<typename T> T& Singleton(){
  static T instance;
  return instance;
}
void func();
int main(){
  AClass ac1 = Singleton<AClass>();
  AClass ac2 = Singleton<AClass>();
  func();
  return 0;
}
[/code]
---------------------------------------------------
[code]
template<typename T> T& Singleton();
class AClass{
  AClass();
  char* storage;
};
void func(){
  AClass ac3 = Singleton<AClass>();
  AClass ac4 = Singleton<AClass>();
}
[/code]
e cmq vedo allocati i 50MB solo una volta, quindi effettivamente trattasi di
singleton. O no?

 singleton. O no?
chiaramente intendevo avanzato step-by-step in debug


si, certo, anche io avevo ottenuto risultati del genere
(abbastanza logici e prevedibili peraltro)
la mia domanda era relativa a cosa dice lo standard in merito
non vorrei che il comportamente dipendesse in qualche modo da scelte
del compilatore/linker
M.
... è anche possibile che mi stia facendo scrupoli inutili!