#1 Le 24/04/2012, à 22:39
- Maneithel
[RÉSOLU]C++ Instancier un classe comprenant un membre static
Bonjour à tous !
Je suis en train d'améliorer mon lot d'outils et j'ai pensé me faire une classe Singleton. J'ai suivi le tutoriel ici et je n'arrive pas à instancier ma classe. J'ai les erreurs suivantes :
main.o: In function `cbl::Singleton<cbl::LonelyClass>::getInstance()':
/home/charles/Workspace/cplusplus/projets/dev_outil_debug-build-desktop/../../libs/libcbl-shared/pattern.hpp:18: undefined reference to `cbl::Singleton<cbl::LonelyClass>::m_instance'
/home/charles/Workspace/cplusplus/projets/dev_outil_debug-build-desktop/../../libs/libcbl-shared/pattern.hpp:19: undefined reference to `cbl::Singleton<cbl::LonelyClass>::m_instance'
/home/charles/Workspace/cplusplus/projets/dev_outil_debug-build-desktop/../../libs/libcbl-shared/pattern.hpp:20: undefined reference to `cbl::Singleton<cbl::LonelyClass>::m_instance'
main.o: In function `cbl::Singleton<cbl::LonelyClass>::kill()':
/home/charles/Workspace/cplusplus/projets/dev_outil_debug-build-desktop/../../libs/libcbl-shared/pattern.hpp:22: undefined reference to `cbl::Singleton<cbl::LonelyClass>::m_instance'
/home/charles/Workspace/cplusplus/projets/dev_outil_debug-build-desktop/../../libs/libcbl-shared/pattern.hpp:23: undefined reference to `cbl::Singleton<cbl::LonelyClass>::m_instance'
main.o:/home/charles/Workspace/cplusplus/projets/dev_outil_debug-build-desktop/../../libs/libcbl-shared/pattern.hpp:24: more undefined references to `cbl::Singleton<cbl::LonelyClass>::m_instance' follow
collect2: ld a retourné 1 code d'état d'exécution
J'ai rassemblé pour vous un code minimal :
pattern.hpp:
#ifndef PATTERN_HPP
#define PATTERN_HPP
#include "libcbl-shared_global.h"
using namespace std;
namespace cbl{
template <typename T> class LIBCBLSHAREDSHARED_EXPORT Singleton
{
/* Use by declaring a subclass, i.e.
* class UniqueObject : public Singleton<UniqueObject>{};
*/
public:
static T *getInstance(){
if( m_instance == NULL )
m_instance = new T;
return ( static_cast<T*> (m_instance) );
}
static void kill(){
if( m_instance != NULL ){
delete m_instance;
m_instance = NULL;
}
}
protected:
Singleton (){}
~Singleton(){}
private:
static T * m_instance;
}; // class Singleton
class LIBCBLSHAREDSHARED_EXPORT LonelyClass
: public Singleton<LonelyClass>
{
friend class Singleton<LonelyClass>;
private:
LonelyClass(){}
~LonelyClass(){}
}; // class LonelyClass
} // namespace cbl
#endif // PATTERN_HPP
main.cpp :
#include <pattern.hpp>
using namespace cbl;
int main()
{
LonelyClass *fh;
fh = LonelyClass::getInstance();
fh->kill();
return 0;
}
Avez-vous un indice ?
EDIT:
cette discussion portait le nom
Difficulté à instancier un Singleton (motif de conception) c++
Changé pour mieux représenter le problème. La solution est au troisième message.
Dernière modification par Maneithel (Le 25/04/2012, à 17:08)
Hors ligne
#2 Le 25/04/2012, à 07:44
- pingouinux
Re : [RÉSOLU]C++ Instancier un classe comprenant un membre static
Bonjour,
Pour essayer de reproduire l'erreur, il faudrait le contenu de libcbl-shared_global.h.
Cordialement
Hors ligne
#3 Le 25/04/2012, à 17:06
- Maneithel
Re : [RÉSOLU]C++ Instancier un classe comprenant un membre static
Bonjour!
Ce fichier contient des macros et des commandes de préprocesseur utilisés par QMake pour générer ces méta-objets.
Pour reproduire, il suffit de retirer les macros LIBCBLSHAREDSHARED_EXPORT et le fichier libcbl-shared et de tout mettre dans un même projet (voir même fichier),
En attendant, voici la solution !
La classe Singleton contient un attribut statique m_instance. Les attributs statiques doivent être initialisé pour pouvoir permettre l'instanciation. voici donc le résultat complet, déconnecté des macros utilisés par QMake pour lier des bibliothèques partagées.
pattern.hpp :
#ifndef PATTERN_HPP
#define PATTERN_HPP
template <typename T> class Singleton
{
public:
static T *getInstance(){
if( m_instance == NULL )
m_instance = new T;
return ( static_cast<T*> (m_instance) );
}
static void kill(){
if( m_instance != NULL ){
delete m_instance;
m_instance = NULL;
}
}
protected:
Singleton (){}
~Singleton(){}
private:
static T * m_instance;
}; // class Singleton
////////
// LA SOLUTION SE TROUVE DANS LES DEUX LIGNES SUIVANTES
template <typename T>
T *Singleton<T>::m_instance = NULL;
// EXEMPLE DE CLASSE QUI NE POURRA ÊTRE INSTANCIÉE QU'UNE SEULE FOIS
// UN GESTIONNAIRE D'ACCÈS À UNE BASE DE DONNÉES EST
// UN BON EXEMPLE OÙ UN SINGLETON EST UN MOTIF DE CONCEPTION UTILE
class LonelyClass
: public Singleton<LonelyClass>
{
friend class Singleton<LonelyClass>;
private:
LonelyClass(){}
~LonelyClass(){}
}; // class LonelyClass
#endif // PATTERN_HPP
main.cpp
#include "pattern.hpp"
int main()
{
LonelyClass *fh;
fh = LonelyClass::getInstance();
// traitements quelconques
fh->kill();
return 0;
}
Merci pour votre temps !
Hors ligne
#4 Le 25/04/2012, à 18:22
- nicolas66
Re : [RÉSOLU]C++ Instancier un classe comprenant un membre static
Une astuce est de maintenir une pile de singleton (dans un singleton_manager par exemple). A chaque appel de `getInstance', on ajoute l'instance dans la pile et à la destruction du singleton_manager, on vide la pile en faisant des appels à `kill'. Très pratique à utiliser
"The computer was born to solve problems that did not exist before." (B. Gates)
Hors ligne
#5 Le 26/04/2012, à 01:31
- Maneithel
Re : [RÉSOLU]C++ Instancier un classe comprenant un membre static
Hey, c'est une bonne idée ! merci
Hors ligne