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

Contribuez C++ Discussion :

[Source][C++]Manageur de ressource generique et intelligent


Sujet :

Contribuez C++

  1. #1
    Membre expérimenté Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Par défaut [Source][C++]Manageur de ressource generique et intelligent
    Bonjours a tous,
    Pour ce premier post sur developpez.com, je vous propose une class qui tente de répondre au problématiques suivantes:

    • Stocker des objets d'un type définie(template)

    • Pouvoir récupérer ces objets a l'aide d'une clé(tableau associatif)

    • Détruire les objets qui ne sont plus utilisés ailleurs que dans le conteneur

    • Et éventuellement créer l'objet demandé si il n'est pas déjà présent dans le conteneur


    Concrètement, il s'agit d'un std::map associant une clé template a un boost::weak_ptr<>, avec une fonction "Factory" que l'on peu lui passer.
    Une map de shared_ptr n'aurait pas permit le delete, c'est pourquoi j'utilise les weak_ptr, qui sont transformé en shared_ptr lorsqu'ils sont requis.

    Avant tout voici le code:

    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    #include <boost/weak_ptr.hpp>
    #include <boost/function.hpp>
    #include <boost/foreach.hpp>
    #include <map>
     
    namespace Blas
    {
      template<class K, class V>
      class weak_map
      {
        typedef std::map<K, boost::weak_ptr<V> > WeakMapType; //Type du conteneur interne
        typedef typename WeakMapType::iterator iterator;      //Type de l'itérateur
        typedef typename WeakMapType::const_iterator const_iterator; //Type de l'itérateur const
        typedef boost::function1<boost::shared_ptr<V>, const K&> Factory; //Type de la fonction de la factory
     
        WeakMapType _weakMap; //Conteneur
        Factory _factory;     //Fonction factory
     
      public:
        //Constructeur et définition du pointeur sur la factory
        weak_map(Factory f = 0):_factory(f)
        {
        }
     
        //Fait un ajout dans le tableau associatif
        void add(const K &key, const boost::shared_ptr<V> &sptr)
        {
          std::pair<iterator, bool> res = _weakMap.insert( std::pair<K, boost::weak_ptr<V> >(key, boost::weak_ptr<V>(sptr)));
          if(res.second == false)
          {
            //Si l'élément existe déjà, il n'a pas été modifié.
            //Donc il faut le faire, car c'est que le pointeur était NULL
            //   (Ou alors il se passe une chose très étrange...)
            boost::weak_ptr<V> &wptr = res.first->second;
            wptr = boost::weak_ptr<V>(sptr);
          }
        }
     
        //Récupère une ressource. (sinon, ou un shared_ptr NULL)
        //(Peut renvoyer les exceptions du _factory)
        boost::shared_ptr<V> get(const K &key)
        {
          iterator iter = _weakMap.find(key);
          if(iter != _weakMap.end())
          {
            //Si on a trouvé l'objet associé à la clé
            boost::weak_ptr<V> &wptrPtr = iter->second;
            if(wptrPtr.expired() == false) //Et qu'il n'a pas déjà été détruit
              return boost::shared_ptr<V>(wptrPtr);
          }
          //Si on a pas trouvé l'objet...
          if(_factory)
          {
            //...et qu'une fonction factory a été définie, on l'utilise
            boost::shared_ptr<V> sptr(_factory(key));
            add(key, sptr);
            return sptr;
          }
     
          //...et que la fonction factory n'est pas définie, on renvoie un shared_ptr NULL
          return boost::shared_ptr<V>();
        }
     
        //Renvoie le nombre de ressources encore allouées
        int getNbUnexpired() const
        {
          int count = 0;
          const_iterator iterEnd = _weakMap.end();
          for(const_iterator pairIter = _weakMap.begin();
              pairIter != iterEnd;
              pairIter++)
          {
            if(pairIter->second.expired() == false)
              count ++;
          }
          return count;
        }
     
      };
    }
    Pour l'exemple, supposons que vous ayez une factory qui vous construise un objet MyObject à partir d'un seul paramètre(pour commencer), disons un int.
    Maintenant vous voulez être sur qu'on ne crée pas en double un MyObject identique dans vote code. Mais que cette objet partagé soit détruit lorsqu'il n'est plus utilisé:

    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
     
    //Ma factory
    shared_ptr<MyObject> factory(int);
     
    //Mon gestionnaire de ressources
    weak_map<int, MyObject> objectMap(factory);
     
    {
      //Comme l'objet n'éxiste pas deja, il sera crée
      shared_ptr<MyObject> obj1 = objectMap.get(586);
     
      //Comme il existe deja, il sera juste partagé entre deux shared_ptr
      shared_ptr<MyObject> obj2 = objectMap.get(586);
    }
    //En sortant du scope, les shared_ptr seront détruit, et l'objet aussi.
    Il est a notez que la fonction factory peut très bien être membre d'une class, à condition d'utiliser boost::bind.
    Au passage, il est tout a fait possible de créer une clef(et donc une factory) avec plusieurs paramètres, en utilisant le boost::tuple. Vous pourrez le voir dans les exemples joints. (Projet code::block/minGW, probablement compilable sur n'importe quel compilo C++ récent, à condition d'inclure boost dans les chemin de recherche des .hpp)

    Ceci dit, ma première question est de savoir si vous trouvez une utilité a cette objet. En effet cette objet semble pouvoir résoudre beaucoup de soucie dans mon code, mais à t'il un réel intérêt d'un point de vu général?

    Si c'est le cas alors comment pourrait-on l'optimiser?
    (oui je sait bien que faire une map de weak_ptr c'est pas optimum^^)

    Et aussi auriez vous des suggestion pour élargir ces possibilité?

    Enfin, si vous avez des critiques, n'hésitez pas!
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. Merci de nous aider à créer des ressources (FAQ et sources)
    Par Community Management dans le forum Evolutions du club
    Réponses: 29
    Dernier message: 19/10/2015, 00h35
  2. Actualité des ressources Business Intelligence : cours, tutoriels, livres, FAQs, glossaire
    Par fafabzh6 dans le forum Forum général Business Intelligence
    Réponses: 3
    Dernier message: 10/03/2012, 12h50
  3. [Ressources] FAQ, SOURCES et INDEX pensez-y
    Par orafrance dans le forum Oracle
    Réponses: 5
    Dernier message: 06/11/2008, 10h17
  4. État des lieux de l'Open Source Business Intelligence
    Par ygrim dans le forum Approche théorique du décisionnel
    Réponses: 15
    Dernier message: 30/07/2008, 17h50

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