Contenu | Rechercher | Menus

Annonce

Le forum rencontre en ce moment quelques soucis de charge, il est possible qu'une erreur soit affichée quand vous postez un message, ne rechargez pas la page au risque de poster une seconde fois votre message

Si vous rencontrez des soucis à rester connecté sur le forum (ou si vous avez perdu votre mot de passe) déconnectez-vous et reconnectez-vous depuis cette page, en cochant la case "Me connecter automatiquement lors de mes prochaines visites".

#1 Le 24/04/2012, à 23:39

[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, à 18:08)

Hors ligne

#2 Le 25/04/2012, à 08:44

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, à 18:06

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, à 19:22

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, à 02:31

Re : [RÉSOLU]C++ Instancier un classe comprenant un membre static

Hey, c'est une bonne idée ! merci smile

Hors ligne

Haut de page ↑