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 :

CRTP et Factory


Sujet :

C++

  1. #1
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 142
    Par défaut CRTP et Factory
    Bonjour à tous,

    J’aimerais utiliser pour mon code du polymorphisme statique.
    En effet, nous voulons absolument éviter tout ce qui est méthode virtuelle pour éviter de gréver les perfs (le profiler de Visual nous a indiqué que l'introspection nous faisait perdre beaucoup de temps, nous sommes sur un logiciel où le besoin de perf est très important).

    J'ai donc pensé à une architecture classique, du type :
    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
    <class T> Base
    {
       void f()
       {
          (static_cast<T*>this)->f() ;
       }
    }
     
    Class DerivedA : public Base<DerivedA>
    {
       void f()
       {
          //Des trucs à faire
       }
    }
     
    Class DerivedB : public Base<DerivedB>
    {
       void f()
       {
          //D’autres trucs à faire
       }
    }
    Et pour savoir quel objet je dois instancier, j'ai en entrée, à l'exécution, un char qui m'indique quel type d'objet je dois utiliser.

    Je voudrais donc utiliser une sorte de Factory pour créer mes objets. Quelque chose de ce style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Base* Factory(char code)
    {
           Base* obj = NULL;
           if (code == ‘a’)
           {
                 obj = new DerivedA();
           }
           else if (code == ‘b’)
           {
                 obj = new DerivedB();
           }
           return obj;
    }
    Ainsi je pourrais avoir un code générique dans le main sans avoir de méthode virtuelle, le rêve
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void caller(char c)
    {
       Base* obj = Factory(c);
       obj->f();
       delete obj;
    }
    Seulement voilà, je ne peux pas renvoyer de Base* étant donné que Base est templaté, il faut donc que je spécialise…, ce que je ne veux pas faire puisque je veux avoir du code générique. oO

    Et j’aimerais en plus éviter l’allocation mémoire (me passer des pointeurs et du new quoi !). En fait je voudrais faire du polymorphisme mais sans pointeur, ce qui semble difficile !

    Si vous avez des suggestions à me faire pour ce petit problème d'architecture, je suis preneur Merci.

  2. #2
    Membre très actif
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Par défaut
    In Bjarne Stroustrup Programming Principles and Practise Using C++, section 14.3.1 :

    We have met people who were terrified of virtual functions "because they were expensive." Why? How expensive? Compared to what? Where would the cost matter? We explain the implementation model for virtual functions so that you won't have such fears. If you need a virtual function call (to select among alternatives at run time) you can't code the functionality to be any faster or to use less memory using other language features.

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Je peux me tromper, mais je ne vois pas beaucoup de possibilité : soit tu manipules en permanence des génériques, soit tu utilises des abstractions et des fonctions virtuelles. Si tu fais du type erasure, d'une façon ou d'une autre, tu auras probablement au mieux le même coût qu'une fonction virtuelle.

    En revanche, on peut faire du polymorphisme sans allocation dynamique. Tes objets peuvent être créer sur la pile (ou dans les données) et ensuite transmis avec un pointeur (ou une référence) vers leur classe de base. Bien sur il faut veiller à ce que l'objet ne soit pas détruit.

    Pour les problèmes de perfs, êtes vous sur que l'appel à la fonction virtuelle est vraiment le point qui grève les perfs ? Une solution est peut être de retravailler l'algo pour introduire la variation du comportement autrement. Mais là, ça ne peut pas être une solution en dehors de ton contexte. Il faut connaître ton algo.

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Le CRTP est une technique qui peut en effet permet d'éviter l'utilisation de fonctions virtuelles, mais ca ne simule qu'un polymorphisme statique, c'est à dire que tout doit pouvoir être déterminé à la compilation.

    Et quand on utilise une factory, c'est justement pour créer des objet dont le type ne sera déterminé qu'à l'execution, il faudrait faire une sorte de "Static_Factory", mais ce n'est pas le même but ...

    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
     
    template<class D>
    struct B
    { void foo() { static_cast<D*>(this)-> foo(); } };
     
    struct E : B<E>
    { void foo() {} };
     
    struct F : B<F>
    { void foo() {} };
     
    template<size_t>
    struct Static_Factory;
     
    template<>
    struct Static_Factory<0>
    { static B<E> create() { return E(); } };
     
    template<>
    struct Static_Factory<1>
    { static B<F> create() { return F(); } };
     
    int main()
    {
      auto b = Static_Factory<0>::create();
      b.foo();
      return EXIT_SUCCESS;
    }
    Quelque chose dans ce gout là. A regarder dans les bibliothèque de méta-prog, il doit y avoir des outils pour faire ce genre de chose.

Discussions similaires

  1. CORBA-Java, utilisation de factory
    Par Xavier_KKVLNT dans le forum CORBA
    Réponses: 3
    Dernier message: 19/05/2005, 19h43
  2. [Data Access Object]Intérêt de la factory ?
    Par le Daoud dans le forum Général Java
    Réponses: 2
    Dernier message: 21/04/2005, 09h06
  3. [Stratégie][Factory]
    Par Sancho dans le forum Général Java
    Réponses: 6
    Dernier message: 17/02/2005, 11h06
  4. [Fabrique] [Java] La "Factory" Késako ?
    Par brousaille dans le forum Design Patterns
    Réponses: 13
    Dernier message: 21/01/2005, 11h53
  5. [Conception][Factory] Packages inheritance
    Par ludovic.fernandez dans le forum Général Java
    Réponses: 5
    Dernier message: 05/07/2004, 17h02

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