Oui, il suffit de définir "static T* getInstance(int)". Mais c'est pas bien. Parce que par définition du Singleton, il n'y a pas de création. On accède juste à un objet déjà créé. Pour ma part, je pense qu'une sémantique comme suit serait plus adaptée:
Deuxième question: est-il possible de rendre cette classe Singleton auto- destructible quand aucun pointeur ne pointe dessus?
Non, là aussi par définition du Singleton. Un Singleton _est_ est _restera_. Quelle sens aurait un Singleton si il était détruit quand rien ne pointe dessus ?
La question qui se pose est: le modèle Singleton est-il une solution judicieuse à ton problème ?
Le 03 Jan 2005 23:56:56 GMT, Michael a écrit:
Bonsoir à tous,
tout d'abord bonne année et bonne santé à vous tous!
Vient ensuite quelques questions sur une classe singleton que j'ai créé:
template <class T> class Singleton { public :
static T* getInstance() { if (!instance) instance = new T; return instance; }
Oui, il suffit de définir "static T* getInstance(int)". Mais c'est pas
bien.
Parce que par définition du Singleton, il n'y a pas de création. On accède
juste à un objet déjà créé. Pour ma part, je pense qu'une sémantique comme
suit serait plus adaptée:
Deuxième question: est-il possible de rendre cette classe Singleton auto-
destructible quand aucun pointeur ne pointe dessus?
Non, là aussi par définition du Singleton. Un Singleton _est_ est
_restera_. Quelle sens aurait un Singleton si il était détruit quand rien
ne pointe dessus ?
La question qui se pose est: le modèle Singleton est-il une solution
judicieuse à ton problème ?
Le 03 Jan 2005 23:56:56 GMT, Michael <michael@no.com> a écrit:
Bonsoir à tous,
tout d'abord bonne année et bonne santé à vous tous!
Vient ensuite quelques questions sur une classe singleton que j'ai créé:
template <class T>
class Singleton
{
public :
static T* getInstance()
{
if (!instance) instance = new T;
return instance;
}
Oui, il suffit de définir "static T* getInstance(int)". Mais c'est pas bien. Parce que par définition du Singleton, il n'y a pas de création. On accède juste à un objet déjà créé. Pour ma part, je pense qu'une sémantique comme suit serait plus adaptée:
Deuxième question: est-il possible de rendre cette classe Singleton auto- destructible quand aucun pointeur ne pointe dessus?
Non, là aussi par définition du Singleton. Un Singleton _est_ est _restera_. Quelle sens aurait un Singleton si il était détruit quand rien ne pointe dessus ?
La question qui se pose est: le modèle Singleton est-il une solution judicieuse à ton problème ?
Le 03 Jan 2005 23:56:56 GMT, Michael a écrit:
Bonsoir à tous,
tout d'abord bonne année et bonne santé à vous tous!
Vient ensuite quelques questions sur une classe singleton que j'ai créé:
template <class T> class Singleton { public :
static T* getInstance() { if (!instance) instance = new T; return instance; }
Oui, il suffit de définir "static T* getInstance(int)". Mais c'est pas bien. Parce que par définition du Singleton, il n'y a pas de création. On accède juste à un objet déjà créé. Pour ma part, je pense qu'une sémantique comme suit serait plus adaptée:
Pour ça, il faudrait en savoir plus. Un modèle de conception n'est pas une recette figée. Peut-être qu'une adaptation gérant quelques instances au lieu d'une seule serait utile dans le cadre du PO.
Oui, il suffit de définir "static T* getInstance(int)". Mais c'est pas
bien.
Parce que par définition du Singleton, il n'y a pas de création. On accède
juste à un objet déjà créé. Pour ma part, je pense qu'une sémantique comme
suit serait plus adaptée:
Pour ça, il faudrait en savoir plus. Un modèle de conception n'est
pas une recette figée. Peut-être qu'une adaptation gérant quelques
instances au lieu d'une seule serait utile dans le cadre du PO.
Oui, il suffit de définir "static T* getInstance(int)". Mais c'est pas bien. Parce que par définition du Singleton, il n'y a pas de création. On accède juste à un objet déjà créé. Pour ma part, je pense qu'une sémantique comme suit serait plus adaptée:
Pour ça, il faudrait en savoir plus. Un modèle de conception n'est pas une recette figée. Peut-être qu'une adaptation gérant quelques instances au lieu d'une seule serait utile dans le cadre du PO.
--drkm
kanze
Michael wrote:
Vient ensuite quelques questions sur une classe singleton que j'ai créé:
template <class T> class Singleton { public :
static T* getInstance() { if (!instance) instance = new T; return instance; }
Faut-il que je passe par des spécialisations templates? Si oui comment je peux faire ça?
Même pas une spécialisation. Pas de template du tout.
Deuxième question: est-il possible de rendre cette classe Singleton auto- destructible quand aucun pointeur ne pointe dessus?
Évidemment (mais ce ne serait plus ce que j'entends par Singleton:-)). À la place d'une référence (ou un pointeur brut), instance renvoie un pointeur intelligent qui gère un compteur.
-- James Kanze GABI Software http://www.gabi-soft.fr Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Michael wrote:
Vient ensuite quelques questions sur une classe singleton que
j'ai créé:
template <class T>
class Singleton
{
public :
static T* getInstance()
{
if (!instance) instance = new T;
return instance;
}
Faut-il que je passe par des spécialisations templates? Si oui
comment je peux faire ça?
Même pas une spécialisation. Pas de template du tout.
Deuxième question: est-il possible de rendre cette classe
Singleton auto- destructible quand aucun pointeur ne pointe
dessus?
Évidemment (mais ce ne serait plus ce que j'entends par
Singleton:-)). À la place d'une référence (ou un pointeur
brut), instance renvoie un pointeur intelligent qui gère un
compteur.
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Faut-il que je passe par des spécialisations templates? Si oui comment je peux faire ça?
Même pas une spécialisation. Pas de template du tout.
Deuxième question: est-il possible de rendre cette classe Singleton auto- destructible quand aucun pointeur ne pointe dessus?
Évidemment (mais ce ne serait plus ce que j'entends par Singleton:-)). À la place d'une référence (ou un pointeur brut), instance renvoie un pointeur intelligent qui gère un compteur.
-- James Kanze GABI Software http://www.gabi-soft.fr Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
kanze
drkm wrote:
"Pierre Lairez" writes:
Seulement comment puis-je la modifier si je veux passer un paramètre lors de la création?
Oui, il suffit de définir "static T* getInstance(int)". Mais c'est pas bien. Parce que par définition du Singleton, il n'y a pas de création. On accède juste à un objet déjà cré é. Pour ma part, je pense qu'une sémantique comme suit serait plus adaptée:
Pour ça, il faudrait en savoir plus. Un modèle de conception n'est pas une recette figée. Peut-être qu'une adaptation gérant quelques instances au lieu d'une seule serait utile dans le cadre du PO.
Tout à fait. J'ai un cas où le singleton est caractèrisé par un paramètre, et ce qu'il faut, c'est une instance unique pour un paramètre donné. Ça marche exactement comme un singleton classique, sauf que la fonction instance prend le paramètre, et j'ai un std::map< ParamType, Singleton* > à la place d'un simple pointeur.
Dans mon cas, ça sert à gérer des « bases de données », mais je le verais aussi pour la gestion des imprimantes, par exemple (une instance de Printer par imprimante), des écrans d'un terminal, des terminaux attachés à une application...
-- James Kanze GABI Software http://www.gabi-soft.fr Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Oui, il suffit de définir "static T* getInstance(int)". Mais
c'est pas bien. Parce que par définition du Singleton, il
n'y a pas de création. On accède juste à un objet déjà cré é.
Pour ma part, je pense qu'une sémantique comme suit serait
plus adaptée:
Pour ça, il faudrait en savoir plus. Un modèle de conception
n'est pas une recette figée. Peut-être qu'une adaptation
gérant quelques instances au lieu d'une seule serait utile
dans le cadre du PO.
Tout à fait. J'ai un cas où le singleton est caractèrisé par un
paramètre, et ce qu'il faut, c'est une instance unique pour un
paramètre donné. Ça marche exactement comme un singleton
classique, sauf que la fonction instance prend le paramètre, et
j'ai un std::map< ParamType, Singleton* > à la place d'un simple
pointeur.
Dans mon cas, ça sert à gérer des « bases de données », mais je
le verais aussi pour la gestion des imprimantes, par exemple
(une instance de Printer par imprimante), des écrans d'un
terminal, des terminaux attachés à une application...
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Oui, il suffit de définir "static T* getInstance(int)". Mais c'est pas bien. Parce que par définition du Singleton, il n'y a pas de création. On accède juste à un objet déjà cré é. Pour ma part, je pense qu'une sémantique comme suit serait plus adaptée:
Pour ça, il faudrait en savoir plus. Un modèle de conception n'est pas une recette figée. Peut-être qu'une adaptation gérant quelques instances au lieu d'une seule serait utile dans le cadre du PO.
Tout à fait. J'ai un cas où le singleton est caractèrisé par un paramètre, et ce qu'il faut, c'est une instance unique pour un paramètre donné. Ça marche exactement comme un singleton classique, sauf que la fonction instance prend le paramètre, et j'ai un std::map< ParamType, Singleton* > à la place d'un simple pointeur.
Dans mon cas, ça sert à gérer des « bases de données », mais je le verais aussi pour la gestion des imprimantes, par exemple (une instance de Printer par imprimante), des écrans d'un terminal, des terminaux attachés à une application...
-- James Kanze GABI Software http://www.gabi-soft.fr Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Michael
class Configuration : public Singleton< Configuration >
en fait, j'imagine.
Oui, oubli de ma part...
Deuxième question: est-il possible de rendre cette classe Singleton auto- destructible quand aucun pointeur ne pointe dessus?
Évidemment (mais ce ne serait plus ce que j'entends par Singleton:-)). À la place d'une référence (ou un pointeur brut), instance renvoie un pointeur intelligent qui gère un compteur.
Ce que je voudrais faire avec ça, c'est par exemple dans le cas de la connexion à une BDD, supprimer l'instance quand il n'y a plus de connexion...
class Configuration : public Singleton< Configuration >
en fait, j'imagine.
Oui, oubli de ma part...
Deuxième question: est-il possible de rendre cette classe
Singleton auto- destructible quand aucun pointeur ne pointe
dessus?
Évidemment (mais ce ne serait plus ce que j'entends par
Singleton:-)). À la place d'une référence (ou un pointeur
brut), instance renvoie un pointeur intelligent qui gère un
compteur.
Ce que je voudrais faire avec ça, c'est par exemple dans le cas de la
connexion à une BDD, supprimer l'instance quand il n'y a plus de
connexion...
class Configuration : public Singleton< Configuration >
en fait, j'imagine.
Oui, oubli de ma part...
Deuxième question: est-il possible de rendre cette classe Singleton auto- destructible quand aucun pointeur ne pointe dessus?
Évidemment (mais ce ne serait plus ce que j'entends par Singleton:-)). À la place d'une référence (ou un pointeur brut), instance renvoie un pointeur intelligent qui gère un compteur.
Ce que je voudrais faire avec ça, c'est par exemple dans le cas de la connexion à une BDD, supprimer l'instance quand il n'y a plus de connexion...
kanze
Michael wrote:
class Configuration : public Singleton< Configuration >
en fait, j'imagine.
Oui, oubli de ma part...
Deuxième question: est-il possible de rendre cette classe Singleton auto- destructible quand aucun pointeur ne pointe dessus?
Évidemment (mais ce ne serait plus ce que j'entends par Singleton:-)). À la place d'une référence (ou un pointeur brut), instance renvoie un pointeur intelligent qui gère un compteur.
Ce que je voudrais faire avec ça, c'est par exemple dans le cas de la connexion à une BDD, supprimer l'instance quand il n'y a plus de connexion...
Et il peut y avoir plusieurs connections ? Ce n'est vraiment pas ce qu'on appelle d'habitude un singleton:-).
Supprimer l'instance quand il n'y a plus de connection est trivial. C'est la classe de connection qui reconnaît que la connection est tombée, n'est-ce pas ? Alors, elle n'a qu'à faire « delete this ». Évidemment, c'est là que le bat blesse, parce qu'il faut aussi trouver tous les pointeurs, et les mettre à zéro. À ma site, il y a un pointeur intelligent qui s'occupe de ce genre de chose (GB_ManagedPtr), mais il faut bien d'abord définir ce que tu veux exactement. (Par exemple, est-ce qu'on laisse tomber la connection exprès quand personne n'en detient un pointeur vers l'instance.)
Enfin, je verrais bien un espèce de ConnectionManager, qui lui serait un singleton (dans le sens classique). Quand un client veut utliser une connection, il s'adresse au CollectionManager en lui donnant l'identificateur voulu ; il reçoit en retour un espèce de shared pointer. Si la connection n'existe pas encore, la CollectionManager se charge de la créer et de le mettre dans un map. Et à l'arrivée à zéro du compteur d'utilisation, le shared pointer s'occupe non seulement de deleter la connection, mais de l'enveler du map.
Je crois que le tout est faisable avec boost::shared_ptr, avec un boost::weak_ptr dans le map, mais je ne connais pas Boost assez bien pour en être sûr. (Boost ne marche pas avec un des compilateurs que je suis obligé à supporter.) Si j'ai bien compris la doc, tu peux créer une classe « Deleter » pour ton objet de connection, et alors, dans la fonction getConnection de ConnectionManager, tu ferais quelque chose comme :
boost::shared_ptr< Connection > ConnectionManager::getConnection( ConnectionId const& id ) { Map::iterator cx = myMap.find( id ) ; boost::shared_ptr< Connection > result ; if ( result != myMap.end() ) { result = cx->second.lock() ; } else { result = boost::shared_ptr< Connection >( new Connection( id ), Deleter( this ) ) ; myMap.insert( Map::value_type( id, boost::weak_ptr< Connection >( result ) ) ); } return result ; }
Deleter, évidemment, est une classe membre de ConnectionManager qui enlève l'entrée dans le map avant d'effacer l'objet.
(Sans garantie. Comme j'ai dit, je ne peux malheureusement pas utiliser Boost pour l'instant.)
-- James Kanze GABI Software http://www.gabi-soft.fr Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Michael wrote:
class Configuration : public Singleton< Configuration >
en fait, j'imagine.
Oui, oubli de ma part...
Deuxième question: est-il possible de rendre cette classe
Singleton auto- destructible quand aucun pointeur ne pointe
dessus?
Évidemment (mais ce ne serait plus ce que j'entends par
Singleton:-)). À la place d'une référence (ou un pointeur
brut), instance renvoie un pointeur intelligent qui gère un
compteur.
Ce que je voudrais faire avec ça, c'est par exemple dans le
cas de la connexion à une BDD, supprimer l'instance quand il
n'y a plus de connexion...
Et il peut y avoir plusieurs connections ? Ce n'est vraiment pas
ce qu'on appelle d'habitude un singleton:-).
Supprimer l'instance quand il n'y a plus de connection est
trivial. C'est la classe de connection qui reconnaît que la
connection est tombée, n'est-ce pas ? Alors, elle n'a qu'à faire
« delete this ». Évidemment, c'est là que le bat blesse, parce
qu'il faut aussi trouver tous les pointeurs, et les mettre à
zéro. À ma site, il y a un pointeur intelligent qui s'occupe de
ce genre de chose (GB_ManagedPtr), mais il faut bien d'abord
définir ce que tu veux exactement. (Par exemple, est-ce qu'on
laisse tomber la connection exprès quand personne n'en detient
un pointeur vers l'instance.)
Enfin, je verrais bien un espèce de ConnectionManager, qui lui
serait un singleton (dans le sens classique). Quand un client
veut utliser une connection, il s'adresse au CollectionManager
en lui donnant l'identificateur voulu ; il reçoit en retour un
espèce de shared pointer. Si la connection n'existe pas encore,
la CollectionManager se charge de la créer et de le mettre dans
un map. Et à l'arrivée à zéro du compteur d'utilisation, le
shared pointer s'occupe non seulement de deleter la connection,
mais de l'enveler du map.
Je crois que le tout est faisable avec boost::shared_ptr, avec
un boost::weak_ptr dans le map, mais je ne connais pas Boost
assez bien pour en être sûr. (Boost ne marche pas avec un des
compilateurs que je suis obligé à supporter.) Si j'ai bien
compris la doc, tu peux créer une classe « Deleter » pour ton
objet de connection, et alors, dans la fonction getConnection de
ConnectionManager, tu ferais quelque chose comme :
boost::shared_ptr< Connection >
ConnectionManager::getConnection(
ConnectionId const& id )
{
Map::iterator cx = myMap.find( id ) ;
boost::shared_ptr< Connection >
result ;
if ( result != myMap.end() ) {
result = cx->second.lock() ;
} else {
result = boost::shared_ptr< Connection >(
new Connection( id ),
Deleter( this ) ) ;
myMap.insert(
Map::value_type(
id,
boost::weak_ptr< Connection >( result ) ) );
}
return result ;
}
Deleter, évidemment, est une classe membre de ConnectionManager
qui enlève l'entrée dans le map avant d'effacer l'objet.
(Sans garantie. Comme j'ai dit, je ne peux malheureusement pas
utiliser Boost pour l'instant.)
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
class Configuration : public Singleton< Configuration >
en fait, j'imagine.
Oui, oubli de ma part...
Deuxième question: est-il possible de rendre cette classe Singleton auto- destructible quand aucun pointeur ne pointe dessus?
Évidemment (mais ce ne serait plus ce que j'entends par Singleton:-)). À la place d'une référence (ou un pointeur brut), instance renvoie un pointeur intelligent qui gère un compteur.
Ce que je voudrais faire avec ça, c'est par exemple dans le cas de la connexion à une BDD, supprimer l'instance quand il n'y a plus de connexion...
Et il peut y avoir plusieurs connections ? Ce n'est vraiment pas ce qu'on appelle d'habitude un singleton:-).
Supprimer l'instance quand il n'y a plus de connection est trivial. C'est la classe de connection qui reconnaît que la connection est tombée, n'est-ce pas ? Alors, elle n'a qu'à faire « delete this ». Évidemment, c'est là que le bat blesse, parce qu'il faut aussi trouver tous les pointeurs, et les mettre à zéro. À ma site, il y a un pointeur intelligent qui s'occupe de ce genre de chose (GB_ManagedPtr), mais il faut bien d'abord définir ce que tu veux exactement. (Par exemple, est-ce qu'on laisse tomber la connection exprès quand personne n'en detient un pointeur vers l'instance.)
Enfin, je verrais bien un espèce de ConnectionManager, qui lui serait un singleton (dans le sens classique). Quand un client veut utliser une connection, il s'adresse au CollectionManager en lui donnant l'identificateur voulu ; il reçoit en retour un espèce de shared pointer. Si la connection n'existe pas encore, la CollectionManager se charge de la créer et de le mettre dans un map. Et à l'arrivée à zéro du compteur d'utilisation, le shared pointer s'occupe non seulement de deleter la connection, mais de l'enveler du map.
Je crois que le tout est faisable avec boost::shared_ptr, avec un boost::weak_ptr dans le map, mais je ne connais pas Boost assez bien pour en être sûr. (Boost ne marche pas avec un des compilateurs que je suis obligé à supporter.) Si j'ai bien compris la doc, tu peux créer une classe « Deleter » pour ton objet de connection, et alors, dans la fonction getConnection de ConnectionManager, tu ferais quelque chose comme :
boost::shared_ptr< Connection > ConnectionManager::getConnection( ConnectionId const& id ) { Map::iterator cx = myMap.find( id ) ; boost::shared_ptr< Connection > result ; if ( result != myMap.end() ) { result = cx->second.lock() ; } else { result = boost::shared_ptr< Connection >( new Connection( id ), Deleter( this ) ) ; myMap.insert( Map::value_type( id, boost::weak_ptr< Connection >( result ) ) ); } return result ; }
Deleter, évidemment, est une classe membre de ConnectionManager qui enlève l'entrée dans le map avant d'effacer l'objet.
(Sans garantie. Comme j'ai dit, je ne peux malheureusement pas utiliser Boost pour l'instant.)
-- James Kanze GABI Software http://www.gabi-soft.fr Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34