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

Comment puis-je instancier des objets C à partir de chaînes de noms de classe ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-18 00:25:10505parcourir

How Can I Instantiate C   Objects from Class Name Strings?

Instanciation d'objet à partir de chaînes de nom de classe

En C, il n'est pas possible d'instancier un objet à partir d'une chaîne contenant le nom de classe sans mappage explicite . Cette limitation provient de la nature statique du C , où les types doivent être connus au moment de la compilation.

Option 1 : Mappage manuel à l'aide de modèles

Vous pouvez créer une fonction de modèle pour chaque classe que vous souhaitez instancier et une carte pour lier les noms de classe aux fonctions de modèle correspondantes. Par exemple :

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

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

Pour instancier un objet, utilisez :

return map[some_string]();

Option 2 : enregistrement du type d'exécution

Vous pouvez avoir des classes s'enregistrer auprès d'un mécanisme statique, puis récupérer les instances de manière dynamique. Cela implique l'utilisation d'une carte singleton pour stocker le nom de classe et les mappages de fonctions. Voici un exemple :

struct BaseFactory {
    static Base * createInstance(std::string const& s) {
        auto it = getMap()->find(s);
        return it != getMap()->end() ? it->second() : nullptr;
    }

    static std::map<std::string, std::function<Base*()>> * getMap() {
        if (!map) { map = new std::map<std::string, std::function<Base*()>>; }
        return map;
    }

private:
    static std::map<std::string, std::function<Base*()>> * map;
};

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

class DerivedB {
private:
    static DerivedRegister<DerivedB> reg("DerivedB");
};

Cette méthode permet l'enregistrement automatique des classes au moment de l'exécution.

Option 3 : Variante Boost

Si vous avez classes sans rapport avec aucune classe de base commune, vous pouvez utiliser la bibliothèque de variantes Boost :

typedef boost::variant<Foo, Bar, Baz> variant_type;
template<typename T> variant_type createInstance() { return variant_type(T()); }

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

Cette technique permet d'instancier des différents types à partir d'une seule chaîne.

En conclusion, C ne dispose pas d'un mécanisme intégré pour l'instanciation d'objets à partir de chaînes de noms de classe. Cependant, en utilisant des modèles, l'enregistrement d'exécution ou la bibliothèque de variantes Boost, vous pouvez obtenir des fonctionnalités similaires.

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