Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#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 smile


"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 smile

Hors ligne