Мне нужен вариантный тип, который содержит экземпляры любого определяемого пользователем класса. Поэтому я использую void*:
typedef boost::variant<void*, int, float, std::string> Tvariant;
Я создал класс-оболочку с картой:
typedef std::map<std::string, Tvariant> Tvalues;
Пример использования:
int x = 123;
attributes.set("int_var", x);
x = attributes.get<int>("int_var");
MyClass* obj = new MyClass();
attributes.set("void*_var", obj);
obj = static_cast<MyClass*>( attributes.get<void*>("void*_var") );
obj = attributes.cast<MyClass*>("void*_var"); // the same
Есть 2 проблемы с этим void* в классе вариантов:
- Копирование атрибутов с указателями на динамически выделенную память опасно и чревато ошибками.
- Пользователь может static_cast void* использовать WrongClass*, а не MyClass*. Он компилируется, но результат непредсказуем.
Возможные решения:
- Используйте boost::shared_ptr‹ void* >.
- Запомните typeid для всех значений void* (при их добавлении) в файле
std::map<void*, typeid> typeid_map
. Когда пользователь запрашивает значение void*, приводя его к любому TClass*, давайте оценим утверждение:assert(typeid_from_typeid_map == typeid(TClass*))
.
Вопросы:
1. Существуют ли другие решения для хранения значений любого определяемого пользователем класса?
2. Может быть, вы порекомендуете лучшие решения для упомянутых проблем и укажете на некоторые другие проблемы?