2017-07-09 1 views
0

Mon intention est, chaque fois que j'ajoute une nouvelle classe dérivée, j'en ai besoin enregistré dans une liste de noms de classe dans un autre objet de classe afin que toutes les nouvelles classes puissent être utilisées pour un processus. Mais faire cela sans écrire quelque chose de plus que d'autres classes à la main prend plus de temps.C++ gérer plusieurs classes dérivées avec des mots-clés statiques ou des modèles indexés

J'ai beaucoup de classes dérivées à maintenir, comme les ajouter à une liste, vérifier leurs noms et des choses similaires. Maintenant, je suis prêt à rendre cela automatisé. Chaque classe dérivée contient un initialiseur de membre statique qui ajoute également son propre nom à la liste statique de la classe de base afin que le programmateur analyse cette liste et gère les préparations.

  • Examinez un dossier contenant des fichiers source (définitions de classes dérivées) avec le même schéma de nommage et construisez-en une liste (encore une fois, en utilisant des noms)
  • chaque classe dérivée possède un numéro de type de modèle et d'itération tout cela peut ne pas convenir à la production ou au moins ne pas fonctionner à tout moment, par exemple, mot-clé statique ne fonctionne pas, sauf si une classe est utilisée une seule fois, mais je ne peux pas initialiser un cours si je ne le connais pas. Le second choix n'est pas sécurisé, le troisième je ne sais pas s'il pourrait planter le programme quand l'index entier du template sort de la frontière.

    Quel est le danger d'incrémenter

    // try until error, can compiler compile this? 
    while(noError) 
    { 
        tryInit(new MyClass<ctr>()).addToList(); 
    } 
    // or 
    tryInit(new MyClass<2>()).addToList(); 
    tryInit(new MyClass<3>()).addToList(); 
    tryInit(new MyClass<4>()).addToList(); 
    tryInit(new MyClass<5>()).addToList(); 
    

    ce qui se passe s'il n'y a pas 5 classes dérivées? Y a-t-il un mot-clé au-delà de l'état statique qui effectue un chargement de classe dès le démarrage du programme, même sans déclaration directe ou autre chose?

  • +1

    Les classes ne sont pas des "modules", et les appeler ainsi obscurcit votre question. –

    +0

    ok la fixer je suis désolé. –

    +1

    Je n'ai aucune idée après avoir lu votre explication de ce que vous essayez de faire. Mais je peux répondre à la question directe. * "Que se passe-t-il s'il n'y a pas 5 classes dérivées?" * Si aucune spécialisation explicite n'est définie pour MyClass <5>, ni pour le modèle principal, vous obtiendrez une erreur de compilation ici. S'il y a une spécialisation explicite, elle sera utilisée. Sinon, le compilateur essaiera d'instancier le modèle principal avec '5' comme argument. –

    Répondre

    1

    Ce que vous décrivez est possible, si un peu dangereux/désagréable

    template<int> 
    struct MyClass : std::false_type {}; 
    
    template<> 
    struct MyClass<0> : std::true_type 
    { 
        static void foo(int i) { std::cout << i << " is useful!" << std::endl; } 
    }; 
    
    // and so on... 
    

    Pour ajouter une nouvelle classe, il suffit d'ajouter une autre spécialisation de MyClass.

    itérer sur tous

    template<int n> 
    void foo_all_(int i) 
    { 
        if constexpr(MyClass<n>::value) 
        { 
         MyClass<n>::foo(i); 
         foo_all_<n + 1>(i); 
        } 
    } 
    
    void foo_all(int i) 
    { 
        foo_all_<0>(i); 
    } 
    

    La partie dangereuse/désagréable est que tout MyClass doit être correctement défini et spécialisés pour que cela fonctionne.

    J'imagine avoir une telle famille de classes est utile que le polymorphisme, ce qui pourrait en faire un peu plus convivial

    struct Base : std::true_type { /* ... */ }; 
    
    template<int> 
    struct MyClass {};  
    
    template<> 
    struct MyClass<0> : Base { /* ... */ }; 
    

    Et cramponnez cas de MyClass avec Base références.

    +0

    Existe-t-il un moyen de forcer ce schéma pour toute nouvelle déclaration de classe afin de garantir qu'aucune erreur ne se produira plus tard? (par exemple en déclarant un virtuel pur pour forcer l'implémentation de celui-ci) –

    +0

    @huseyintugrulbuyukisik Oui, il suffit d'utiliser du virtuel pur comme vous l'avez dit dans 'Base' –