IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Singleton: undefined method


Sujet :

C++

  1. #1
    Membre chevronné Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Par défaut Singleton: undefined method
    Bonsoir,

    Je veux faire un scheduler. Il s'agit d'une classe singleton à laquelle on va ajouter des taches (interface Task). Les Task implémentent une méthode pour l'opérateur <, ce qui permet au scheduler d'ordonnacer les tâches selon
    l'heure à laquelle on voudrait les lancer et leur priorité.

    A terme, l'objectif est que le scheduler fasse tourner un thread qui va entretenir une horloge temps réel et une horloge virtuelle qui vont servir à lancer les différentes tâches (méthode virtuelle pure "run").

    Voilà pour le décor.

    J'ai commencé par faire un singleton en reprenant ce que j'ai trouvé sur un des tutos de developpez (au final ça ne fonctionnait pas, j'en suis revenu à un bête copié/collé), ainsi que ma classe Scheduler.

    Malheureusement, quand j'essaye de récupérer mon scheduler, le compilo me dit que la méthode n'est pas définie..

    La class template singleton
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    /*
     * Singleton.h
     *
     *  Created on: 5 sept. 2010
     *      Author: seeme
     */
    //Not safe in multithread! Be carreful..
     
    #ifndef SINGLETON_H_
    #define SINGLETON_H_
     
    template <class T> class Singleton{
    public:
    	static T* get();
    	static void kill();
     
    protected:
    	static T* m_i;
     
    private:
    	T& operator=(const T&){}
    };
     
    #endif /* SINGLETON_H_ */
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    /*
     * Singleton.h
     *
     *  Created on: 5 sept. 2010
     *      Author: seeme
     */
    //Not safe in multithread! Be carreful..
     
    #include "Singleton.h"
     
    template <class T> T* Singleton<T>::m_i=0;
     
     
    template <class T>  T* Singleton<T>::get(){
            if(m_i==0){
                    m_i=new T();
            }
            return m_i;
    }
     
    template <class T> void Singleton<T>::kill(){
            delete m_i;
            m_i=0;
    }
    Et le scheduler
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    /*
     * Scheduler.h
     *
     *  Created on: 5 sept. 2010
     *      Author: seeme
     */
     
    #ifndef SCHEDULER_H_
    #define SCHEDULER_H_
     
    #include <list>
    #include <ctime>
    #include "Task.h"
    #include "../Tools/Singleton.h"
    #include <ostream>
    #include <iterator>
     
    class Scheduler: public Singleton<Scheduler>{
     
        friend Scheduler* Singleton<Scheduler>::get();
        friend void Singleton<Scheduler>::kill();
     
     
    private:
    	std::list<Task*>* m_taskList;
    	unsigned long m_virtualTime;
    	void run();
    	Scheduler();
    	~Scheduler();
     
    public:
     
    	void addTask(Task* t);
     
     
    	virtual void print(std::ostream& o) const {
    		o << "Scheduler: " << std::endl;
    		std::list<Task*>::iterator it;
    		it = m_taskList->begin();
    		while(it != m_taskList->end()){
    			o << **it << std::endl;
    			it++;
    		}
    	}
     
    	friend std::ostream& operator<<(std::ostream& out, const Scheduler& v){
    		v.print(out);
    		return out;
    	}
     
    };
     
    struct Compar
    {
      bool operator()(Task* left, Task* right){
          return (*left < *right);
      }
    };
     
    #endif /* SCHEDULER_H_ */
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    /*
     * Scheduler.cpp
     *
     *  Created on: 5 sept. 2010
     *      Author: seeme
     */
     
    #include "Scheduler.h"
    #include <iostream>
     
    Scheduler::Scheduler() {
    	m_taskList = new std::list<Task*>();
    	m_virtualTime = 0;
    	std::cout << "Constructor" << std::endl;
    }
     
    Scheduler::~Scheduler() {
    	//All remaining task are to be deleted
    	while(m_taskList->begin() != m_taskList->end())
    		delete *m_taskList->begin();
     
    	std::cout << "Destructor" << std::endl;
    }
     
    void Scheduler::addTask(Task* t){
    	m_taskList->push_back(t);
    	m_taskList->sort(Compar());
    }
    et un exemple d'utilisation qui plante lamentablement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    /*
     * Main.cpp
     *
     *  Created on: 29 août 2010
     *      Author: seeme
     */
     
    #include "Main.h"
    #include "Scheduler/Scheduler.h"
    #include <iostream>
     
    using namespace std;
     
    int main(int argc, char**argv){
     
    	Scheduler::get(); // <-- undifined ref to Singleton<Scheduler>::get()
     
    	/*Scheduler * s = Singleton<Scheduler>::get();
    	s->addTask(new Task("Une tache", 10, 1, 1, NORMAL));
     
     
    	Scheduler::kill();*/
    	return 0;
    }
    Merci d'avance
    Seeme

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 29
    Par défaut
    Salut,
    le problème vient du fait que tu a séparé la déclaration et l'implémentation de ton template Singleton (c'est possible de le faire mais il faut faire plus attention => FAQ). Met tout dans Singleton.h et ça devrait aller mieux.

  3. #3
    Membre chevronné Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Par défaut
    Merci beaucoup...

    En conclusion, je suis un boulet et j'ai perdu ma soirée :p

    Jamais ça ne me paraitra logique ce système de .h / .cpp avec les templates..

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,
    Citation Envoyé par seeme Voir le message
    Merci beaucoup...

    En conclusion, je suis un boulet et j'ai perdu ma soirée :p

    Jamais ça ne me paraitra logique ce système de .h / .cpp avec les templates..
    Le fait est que l'utilisation des template revient à dire au compilateur
    je ne sais pas quel type de données je vais manipuler, mais je sais comment je vais le faire
    De ce fait, le compilateur ne peut absolument pas prévoir la taille des données manipulées tant... qu'on ne précise pas le type de celles-ci.

    Il ne pourra donc créer le code binaire exécutable que... lorsqu'il saura quelle donnée est réellement manipulée

    Si tu sépares l'implémentation des différentes fonctions de ta classes et la définition de cette dernière, il faudra donc que tu inclue l'implémentation des fonctions lorsque tu souhaite manipuler un type d'objet particulier

    Mais comme il est communément admis qu'il ne faut pas inclure les fichier *.cpp, il est préférable de ne pas placer l'implémentation dans un fichier *.cpp, pour éviter toute confusion.

    Si tu souhaite effectivement séparer la définition d'une classe template et l'implémentation de ses fonctions, tu peux le faire, mais tu dois alors veiller à utiliser une autre extension pour le fichier d'implémentation (*.impl ou *.tpp, par exemple), de manière à ce que celui qui lira ton code ne se pose pas la question "mais pourquoi diable inclut-il un *.cpp... il ne sait pas que c'est pas recommandé "
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [PDO] Call to undefined method PDOStatement::lastinsertid()
    Par megacool dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 18/10/2008, 15h32
  2. [Artichow] Call to undefined method Graph::getDrawer()
    Par belocom dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 17/04/2008, 22h56
  3. Réponses: 0
    Dernier message: 25/02/2008, 17h28
  4. erreur 1180: Call to a possibly undefined method
    Par Tosh dans le forum ActionScript 3
    Réponses: 2
    Dernier message: 09/12/2007, 23h02
  5. undefined method `cattr_accessor' for ActiveRecord::Base:Cl
    Par r0nsync dans le forum Ruby on Rails
    Réponses: 2
    Dernier message: 02/08/2007, 14h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo