Maison >développement back-end >C++ >C peut-il instancier des objets à partir de chaînes de noms de classe ?

C peut-il instancier des objets à partir de chaînes de noms de classe ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-26 05:37:44392parcourir

Can C   Instantiate Objects from Class Name Strings?

Les objets peuvent-ils être instanciés à partir de chaînes de noms de classe en C ?

Existe-t-il un mécanisme en C pour instancier des objets à partir de chaînes représentant leurs noms de classe , éliminant le besoin de définir explicitement des instructions if-else pour chaque classe dérivée potentielle dans une usine class ?

Problème :

Considérez la structure de classe suivante :

class Base;
class DerivedA : public Base;
class DerivedB : public Base;
// etc...

Et une classe d'usine correspondante, BaseFactory, qui crée des instances de classes dérivées classes basées sur une chaîne de nom de classe spécifiée :

class BaseFactory {
public:
  BaseFactory(std::string &sClassName) { msClassName = sClassName; };

  Base * Create() {
    if(msClassName == "DerivedA") {
      return new DerivedA();
    }
    else if(msClassName == "DerivedB") {
      return new DerivedB();
    }
    // etc...
  };

private:
  string msClassName;
};

Cependant, cette approche nécessite de spécifier explicitement chaque classe dérivée au sein BaseFactory, qui peut devenir fastidieux à mesure que le nombre de classes dérivées augmente.

Solution :

Contrairement à des langages comme C#, C ne fournit pas intrinsèquement de mécanisme pour créer dynamiquement objets basés sur les informations de type d’exécution. Pour obtenir une fonctionnalité similaire, on peut envisager de construire un mappage entre les noms de classe et les fonctions de création d'objet :

template<typename T> Base * createInstance() { return new T; }

typedef std::map<std::string, Base*(*)()> map_type;

map_type map;
map["DerivedA"] = &createInstance<DerivedA>;
map["DerivedB"] = &createInstance<DerivedB>;

En utilisant cette carte, l'instanciation d'objet devient :

return map[some_string]();

Alternativement, on peut enregistrer classes dérivées automatiquement lors de l'initialisation du programme :

template<typename T>
struct DerivedRegister : BaseFactory { 
    DerivedRegister(std::string const& s) { 
        getMap()->insert(std::make_pair(s, &createT<T>));
    }
};

// in derivedb.hpp
class DerivedB {
    ...;
private:
    static DerivedRegister<DerivedB> reg;
};

// in derivedb.cpp:
DerivedRegister<DerivedB> DerivedB::reg("DerivedB");

Cette approche élimine le besoin d'enregistrement manuel de la classe, car elle se produit automatiquement lorsque la classe est défini.

Résumé :

Bien que C ne prenne pas directement en charge l'instanciation d'objet à partir de chaînes de noms de classe, ces techniques fournissent un moyen d'obtenir des fonctionnalités similaires en mappant les noms de classe aux objets fonctions de création ou en automatisant le processus d'inscription.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn