Question

J'ai appris le C ++ à partir de C #, où je me suis habitué à utiliser des fournisseurs de services: en gros un dictionnaire < Type, objet > ;. Malheureusement, je n'arrive pas à comprendre comment faire cela en C ++. Donc, les questions sont essentiellement:

  1. Comment créer un dictionnaire en C ++?

  2. Comment utiliser "Type" avec, dans la mesure où je sais qu'il n'y a pas de "Type" en C ++.

  3. Comme ci-dessus, mais avec 'objet'.

Merci!

Était-ce utile?

La solution

Je suppose que vous essayez de mapper un type sur une instance d'objet unique. Vous pouvez essayer quelque chose dans ce sens:

#include <typeinfo>
#include <map>
#include <string>
using namespace std;

class SomeClass
{
public:
    virtual ~SomeClass() {} // virtual function to get a v-table
};

struct type_info_less
{
    bool operator() (const std::type_info* lhs, const std::type_info* rhs) const
    {
        return lhs->before(*rhs) != 0;
    }
};

class TypeMap
{
    typedef map <type_info *, void *, type_info_less> TypenameToObject;
    TypenameToObject ObjectMap;

public:
    template <typename T> 
    T *Get () const
    {
        TypenameToObject::const_iterator iType = ObjectMap.find(&typeid(T));
        if (iType == ObjectMap.end())
            return NULL;
        return reinterpret_cast<T *>(iType->second);
    }
    template <typename T> 
    void Set(T *value) 
    {
        ObjectMap[&typeid(T)] = reinterpret_cast<void *>(value);
    }
};

int main()
{
    TypeMap Services;
    Services.Set<SomeClass>(new SomeClass());
    SomeClass *x = Services.Get<SomeClass>();
}

En C ++, les types ne sont pas des objets de première classe à part entière, mais au moins le nom du type va être unique, vous pouvez donc y entrer.

Éditer: les noms ne sont pas vraiment uniques, donc gardez les pointeurs type_info et utilisez la méthode before pour les comparer.

Autres conseils

Vous voudrez probablement consulter le modèle de carte STL . C ++ a certainement des types (difficile d’avoir un héritage sans lui), mais pas de définition spécifique & "Type &"; classe.

La STL a deux conteneurs associatifs: std::map<K,V> and std :: multimap. Il y a aussi std::set<V> qui devrait être un adaptateur de std::map<V,void>, mais en tant que tel, ce n'est pas un conteneur associatif. La carte multiple est similaire à la carte, mais elle autorise plusieurs clés identiques dans le même conteneur. Les éléments map et multimap contiennent tous deux des éléments de type std::pair<K,V>. En d'autres termes, std::map<K,V>::value_type == std::pair<K,V>, mais std::map<K,V>::key_type == K et std::map<K,V>::mapped_type == V.

En ce qui concerne & "Tapez &", je ne suis pas tout à fait sûr de ce que vous voulez dire. Si vous voulez parler de classes paramétrées, C ++ appelle cette & "Programmation de modèles &" Ou & "Programmation générique &"; Dans ce qui précède, std::map<K,V> est paramétré sur K et V pour le type de clé et le type de valeur. C ++ prend également en charge les fonctions de modèle:

template<typename T>
void f(T o);

déclarera une fonction qui prend en paramètre n'importe quel type, y compris les types primitifs. C ++ ne prend pas en charge la résolution de type générique, de sorte que le type T doit appartenir à une certaine hiérarchie. Pour le moment, tout ce que vous pouvez faire est de supposer que le type passé appartient bien à la hiérarchie correcte, et le compilateur se plaindra si vous essayez d'appeler une fonction non déclarée sur un objet de ce type.

template<typename T>
void f(T o) {
    o.do_it();
}

Ce qui précède fonctionne tant que T définit la méthode do_it().

Un dictionnaire me ressemble à une carte STL: std::map<K, T>. Jetez un coup d’œil à la bibliothèque de modèles standard: c’est génial. Cela fait partie de ANSI C ++ depuis un moment. Microsoft a une belle implémentation de PJ Plauger, si je me souviens bien.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top