Поставщики услуг C ++
-
03-07-2019 - |
Вопрос
Я изучал C ++, исходя из C #, где я привык пользоваться услугами поставщиков услуг:в основном это Словарь<Type, object="">.К сожалению, я не могу понять, как это сделать на C ++.Итак, вопросы в основном таковы:
Как бы я создал словарь на C ++.
Как бы я мог использовать 'Type' с ним, насколько я знаю, в C ++ нет 'Type'.
То же, что и выше, но с 'object'.
Спасибо!
Решение
Я предполагаю, что вы пытаетесь сопоставить тип с одним экземпляром объекта.Вы могли бы попробовать что-то в этом роде:
#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>();
}
В C ++ типы сами по себе не являются объектами первого класса, но, по крайней мере, имя типа будет уникальным, так что вы можете использовать его как ключ.
Редактировать:На самом деле уникальность имен не гарантируется, поэтому придерживайтесь указателей type_info и используйте метод before для их сравнения.
Другие советы
Вы, вероятно, хотите взглянуть на Шаблон карты STL.В C ++, безусловно, есть типы (трудно иметь наследование без этого), просто нет определенного класса "Type".
STL имеет два ассоциативных контейнера: std::map<K,V> and
std:: мультимап.Существует также std::set<V>
который должен быть адаптером std::map<V,void>
, но как таковой он не является ассоциативным контейнером.Multimap аналогичен map, только он допускает несколько идентичных ключей в одном контейнере.Как карта, так и мультимап содержат элементы типа std::pair<K,V>
.Другими словами, std::map<K,V>::value_type == std::pair<K,V>
, но std::map<K,V>::key_type == K
и std::map<K,V>::mapped_type == V
.
Что касается "Типа", я не совсем уверен, что вы имеете в виду.Если вы имеете в виду параметризованные классы, то C ++ называет это "Шаблонным программированием" или "Универсальным программированием".В приведенном выше, std::map<K,V>
параметризуется по K и V для типа ключей и типа значений.C ++ также поддерживает шаблонные функции:
template<typename T>
void f(T o);
объявит функцию, которая принимает в качестве параметра вообще любой тип, включая примитивные типы.C ++ не поддерживает разрешение универсального типа, так что тип T должен иметь определенную иерархию.На данный момент все, что вы можете сделать, это просто предположить, что переданный тип действительно имеет правильную иерархию, и компилятор будет жаловаться, если вы попытаетесь вызвать необъявленную функцию над объектом этого типа.
template<typename T>
void f(T o) {
o.do_it();
}
Описанное выше будет работать до тех пор, пока T определяет метод do_it()
.
Для меня словарь звучит как карта STL: std::map<K, T>
.Взгляните на Стандартную библиотеку шаблонов - она великолепна.Некоторое время это было частью ANSI C ++.У Microsoft есть хорошая реализация от PJ Plauger, если я правильно помню.