Si elle aide, vous pouvez prendre la réponse de Hitesh, et d'ajouter:
struct luaRegisterManager {
template <typename T>
void registrate() {
T::registrate();
// do something else to record the fact that we've registered -
// perhaps "registrate" should be returning some object to help with that
}
};
Puis:
int main() {
luaRegisterManager lrm;
lrm.registrate<someClass>();
lrm.registrate<someOtherClass>();
}
Plus généralement, si vous voulez introduire un polymorphisme dynamique en C++, alors vous avez besoin un objet, pas seulement une classe. Encore une fois, peut-être que les diverses fonctions register
devraient renvoyer des objets, avec une classe de base d'interface commune registeredClass
, ou classRegistrationInfo
, ou quelque chose du genre.
pourrait-elle fournir un exemple de ce que vous sentez que vous avez besoin polymorphisme dynamique? Le code de Hitesh correspond précisément à votre seul exemple, pour autant que je puisse le voir, de sorte que cet exemple ne doit pas couvrir tous vos cas d'utilisation prévus. Si vous écrivez le code qui l'utilisera, vous saurez peut-être comment l'implémenter, ou peut-être quelqu'un pourra vous conseiller.
Quelque chose d'autre qui pourrait aider:
#include <iostream>
#include <string>
#include <vector>
struct Registered {
virtual std::string name() = 0;
virtual ~Registered() {}
Registered() {
all.push_back(this);
}
static std::vector<Registered*> all;
};
std::vector<Registered*> Registered::all;
typedef std::vector<Registered*>::iterator Iter;
template <typename T>
struct RegisteredT : Registered {
std::string n;
RegisteredT(const std::string &name) : n(name) { T::registrate(); }
std::string name() { return n; }
// other functions here could be implemented in terms of calls to static
// functions of T.
};
struct someClass {
static Registered *r;
static void registrate() { std::cout << "registering someClass\n"; }
};
Registered *someClass::r = new RegisteredT<someClass>("someClass");
struct someOtherClass {
static Registered *r;
static void registrate() { std::cout << "registering someOtherClass\n"; }
};
Registered *someOtherClass::r = new RegisteredT<someOtherClass>("someOtherClass");
int main() {
for (Iter it = Registered::all.begin(); it < Registered::all.end(); ++it) {
std::cout << (*it)->name() << "\n";
}
}
Il y a toutes sortes de problèmes avec ce code si vous essayez de le diviser entre les unités de compilation multiples. En outre, ce genre de chose conduit à des rapports erronés de détecteurs de fuite de mémoire à moins que vous écrivez aussi du code pour tout détruire à la fin, ou utiliser un vecteur de shared_ptr
, vecteur de pointeur Boost, etc Mais vous voyez l'idée générale peut "s'enregistrer", et que vous avez besoin d'un objet pour faire des appels virtuels.
En C++ vous essayez généralement d'éviter l'initialisation statique, bien que, en faveur d'une sorte d'injection setup/dépendance au début de votre programme. Normalement, vous devriez simplement lister toutes les classes qui vous intéressent (en appelant une fonction sur chacune) plutôt que d'essayer de le faire automatiquement.
J'ai pensé à cela, mais ce n'est pas très agréable du point de vue de la conception. Rendons-le un peu plus complexe, et disons que je voudrais laisser un "gestionnaire de registre lua" connaître chaque type de classe qui devrait s'inscrire auprès de Lua, (donc dans l'ensemble, je peux faire "pour chaque classe inscrite, Classe :: register(), en utilisant le polymorphisme) – Goles
@ Mr.Gando: alors choisissez une langue qui est plus agréable du point de vue design ;-) Les classes ne sont pas des objets de première classe en C++, elles ne présentent pas de polymorphisme (une instance de someClass est une instance de registerInterface, mais someClass lui-même n'a pas de type lié au type de registerInterface lui-même), et vous ne pouvez pas vraiment itérer sur les collections de ces classes –
Les classes C++ ne sont pas des objets de première classe C++ n'est pas aussi orienté objet que Ruby ou Objective-C, où vous pourriez avoir une collection d'objets de classe que vous avez parcourus et que vous avez appelée méthodes – Hitesh