c++ d'une usine automatique de l'enregistrement des types dérivés
Comme beaucoup avant moi, j'essaie donc d'obtenir mon des types dérivés pour enregistrer automatiquement avec mon usine. J'ai lu beaucoup de question et a essayé de se concentrer sur ce que je n'ai pas l'y trouver.
J'ai tout fonctionne bien sauf l'enregistrement automatique.
Mes Objectifs:
- enregistrer automatiquement toute classe dérivée de ma classe de base Base
- seulement les classes que je marque comme enregistrable
- non seulement directe de sous-classes de Base
- ex: de Base -> Périphérique> Caméra -> Webcam
- ce serait en utilisant le PFI comme décrit dans cette question dificile
- un minimum de changements pour les classes je veux enregistré - les nuls preuve
- préférez à l'aide d'un registrator classe que les macros
- comme dans cette question, mais je ne sais pas si cela dépend de PFI
Ce que j'ai:
template <class T>
class abstract_factory
{
public:
template < typename Tsub > static void register_class();
static T* create( const std::string& name );
private:
//allocator<T> is a helper class to create a pointer of correct type
static std::map<std::string, boost::shared_ptr<allocator<T> > > s_map;
};
- basé sur un modèle abstrait de l'usine, avec std::string comme type de clé
- abstract factory a tous les membres et méthodes statique
- nom de la classe est récupéré automatiquement avec typeid (pas besoin de texte nom lors de l'inscription)
- enregistrement en appelant:
abstract_factory<Base>::register_class<MyDerived>();
Ce que j'ai essayé (ou voudrais, mais ne savez pas comment correctement):
registrator<Derived> class
: templateded classe est instanciée de façon statique dansDerived.cpp
et doit appelerabstract_factory::register_class<Derived>()
dans son constructeur- n'est jamais appelé ou instancié
- si je fais une instance de
Derived
dansmain()
cela fonctionne -> un peu de défaites le but si
- déclarer une simple variable statique dans chaque
Derived.hpp
et le mettre à la statique de la méthode d'enregistrement enDerived.cpp
-> encore une fois, n'est jamais appelé. - faire
abstract_factory
un vrai singleton au lieu d'avoir tout ce que statique?
Pourrait utiliser tous les conseils, petits ou grands, merci.
OriginalL'auteur Alex | 2012-04-02
Vous devez vous connecter pour publier un commentaire.
- Je utiliser un singleton avec un membre de l'enregistrement, en gros:
À l'aide de Loki je puis avoir quelque chose le long de ces lignes:
L'inscription se fait généralement à l'aide d'une macro tels que:
Cette configuration a un certain nombre d'avantages:
L'invocation de la macro dans le .fichier cpp est suffisant pour obtenir le type enregistré au démarrage pendant l'initialisation statique. Cela fonctionne dandy enregistrer pour le cas où le type d'enregistrement est une partie d'une bibliothèque statique, auquel cas il ne sera pas inclus dans votre binaire. Les seules solutions qui compile l'enregistrement en tant que partie de la bibliothèque, j'ai vu le travail est d'avoir un énorme fichier de l'enregistrement explicitement comme une partie de une sorte de routine d'initialisation. Au lieu de cela ce que je fais aujourd'hui est d'avoir un dossier client avec ma lib de laquelle l'utilisateur comprend qu'une partie de la binaire construire.
À partir de votre liste d'exigences, je crois que cela permet de tout enregistrer pour l'utilisation d'un registrator classe.
Derived classes
sont là. Savez-vous comment gérer à l'exportation de ces symboles de toute façon?Salut Ylisar, auriez-vous l'esprit de prendre un coup d'oeil à ma réponse et me dire votre opinion à ce sujet. J'ai un peu l'impression que quelque chose est incorrect avec elle, mais je ne peux pas le nom.
pouvez-vous préciser ce que vous faites dans la macro pour l'inscription ?
Notez que cela ne fonctionnera pas si vous vous enregistrez vos usines dans les unités de traduction qui sont compilés dans une bibliothèque statique. L'éditeur de liens est possible de traquer les variables globales parce qu'ils ne sont pas ODR utilisé n'importe où.
OriginalL'auteur Ylisar
--- inscription.h ---
--- registration.cpp ---
--- registration_ext.cpp ---
Ensuite compilé avec:
Lors de l'exécution à:
Donc, il semble avoir enregistré les classes avant principal est appelé.
Edit:
J'ai remarqué que cette solution est dépendant de l'implémentation. En vertu de 3.6.2 la norme C++ dit:
Bon point. C'est plus intéressant, j'ai modifié ma réponse un peu maintenant, et il semble fonctionner avec une liaison externe. Je crois que cette réponse se trouve à la frontière de comportement indéfini terre (probablement à l'intérieur). J'aimerais connaître votre opinion à ce sujet.
OriginalL'auteur enobayram