В моей программе, я нахожу ситуацию, в которой я хочу UserClass
чтоКак создать класс, содержащий разные типы классов, и вызвать членов этих объектов?
- представляет собой контейнер, который может содержать разнородные типы
- могут вызывать функции-члены объектов, проводимых.
Набор типов, которые хранятся, ограничен и известен во время компиляции. На самом деле, все типы просто отличаются от template
специализаций.
Этот код иллюстрирует ситуацию:
class ArrayBase { /*etc.*/ }; // definition not changeable
template <class T>
class TypedArray : public ArrayBase // definition not changeable
{
/*more functionality needed by SpecializedArray.*/
}
template<class T>
class SpecializedArray : public TypedArray<T>
{
public:
void newFunctionalityMember() { /*etc.*/ };
};
class UserClass
{
addArray(arrayElmentTypeEnum_t t)
{
switch(t) {
case float_id:
_elementArrays.push_back(new SpecializedArray<float>());
break;
case double_id:
_elementArrays.push_back(new SpecializedArray<double>());
break;
default:
break;
}
void doSomethingWithASpecializedArray(int num)
{
// using _elementArrays[num], call the correct newFunctionalityMember()
}
private:
std::vetor<storagePtr_t> _elementArrays;
}
Без какой-то мольбы, я не имею возможность изменить ArrayBase
или TypedArray
. Я оставил storagePtr_t
Тип неопределенный, поскольку какой тип он должен быть, является ключевой частью моего вопроса.
Я могу придумать одно решение, показанное ниже. Но какая боль! Это очень много кода, чтобы иметь в любом месте UserClass
, что мне нужно получить доступ к элементам элемента. Есть ли лучший способ?
boost library is fair game.
моя техника:
storagePtr_t
является ArrayBase*
, arrayElmentTypeEnum_t
будет std::type_info*
UserClass::doSomethingWithASpecializedArray(int num)
{
// these two both uniquely identified by num.
storagePtr_t * bptr = _elementArrays[num];
arrayElmentTypeEnum_t typekey = ...
if (typekey == &typeid(SpecializedArray<float>)) {
D<float> * dptr = static_cast<SpecializedArray<float>*>(bptr);
dptr->newFunctionalityMember();
} else if (typekey == &typeid(SpecializedArray<double>)) {
D<float> * dptr = static_cast<SpecializedArray<double>*>(bptr);
dptr->newFunctionalityMember();
} else if (typekey == &typeid(SpecializedArray<int>)) {
D<float> * dptr = static_cast<SpecializedArray<int>*>(bptr);
dptr->newFunctionalityMember();
}
}
к сожалению, я нашел мой ранее [вопрос] (http://stackoverflow.com/questions/8736923/cast-base-class-pointer-to - на основе одного из нескольких возможных вариантов-типа-указателя) не содержало достаточно подробностей моего дела, чтобы вымыть полезное решение. – NoahR
Почему вы не можете использовать 'UserClass' также' template'? Это спасет вас от множества беспорядков, не так ли? – iammilind