Provider di servizi C ++
-
03-07-2019 - |
Domanda
Sto imparando il C ++, proveniente da C #, dove mi sono abituato a usare i fornitori di servizi: fondamentalmente un Dizionario < Tipo, oggetto > ;. Sfortunatamente, non riesco a capire come farlo in C ++. Quindi le domande sono fondamentalmente:
-
Come farei un dizionario in C ++.
-
Come userei 'Type' con esso, per quanto ne so non c'è 'Type' in C ++.
-
Come sopra, ma con "oggetto".
Grazie!
Soluzione
Suppongo che tu stia provando a mappare un tipo su una singola istanza di oggetto. Puoi provare qualcosa del genere:
#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>();
}
In C ++ i tipi non sono oggetti di prima classe a sé stanti, ma almeno il nome-tipo sarà univoco, quindi puoi digitarlo.
Modifica: in realtà i nomi non sono garantiti come univoci, quindi tieni i puntatori type_info e usa il metodo before per confrontarli.
Altri suggerimenti
Probabilmente vuoi dare un'occhiata al modello di mappa STL . C ++ ha certamente dei tipi (difficile da avere ereditarietà senza di essa), solo nessun & Quot definito; Tipo & Quot; Classe.
L'STL ha due contenitori associativi: std::map<K,V> and
std :: multimap. C'è anche std::set<V>
che dovrebbe essere un adattatore di std::map<V,void>
, ma come tale non è un contenitore associativo. La multimappa è simile alla mappa, solo consente più chiavi identiche all'interno dello stesso contenitore. Sia la mappa che la multimappa contengono elementi di tipo std::pair<K,V>
. In altre parole, std::map<K,V>::value_type == std::pair<K,V>
, ma std::map<K,V>::key_type == K
e std::map<K,V>::mapped_type == V
.
Per quanto riguarda " Digita " ;, Non sono del tutto sicuro di cosa intendi. Se intendete classi parametrizzate, C ++ chiama questo & Quot; Template Programming & Quot; oppure & Quot; Programmazione generica & Quot ;. In quanto sopra, std::map<K,V>
è parametrizzato su K e V per il tipo di chiavi e il tipo di valori. C ++ supporta anche le funzioni del modello:
template<typename T>
void f(T o);
dichiarerà una funzione che accetta come parametro qualsiasi tipo, inclusi i tipi primitivi. C ++ non supporta la risoluzione di tipo generico, tale che il tipo T deve avere una certa gerarchia. Per ora, tutto ciò che puoi fare è solo supporre che il tipo passato sia effettivamente della gerarchia corretta e il compilatore si lamenterà se provi a chiamare una funzione non dichiarata su un oggetto di quel tipo.
template<typename T>
void f(T o) {
o.do_it();
}
Quanto sopra funzionerà finché T definisce il metodo do_it()
.
Per me un dizionario sembra una mappa STL: std::map<K, T>
. Dai un'occhiata alla Libreria dei modelli standard: è geniale. Fa parte di ANSI C ++ da un po '. Microsoft ha una buona implementazione da PJ Plauger, se ricordo bene.