Считай, у меня есть куча указателей на разные объекты разных классов
class1* obj1;
class2* obj2;
class3* obj3;
и у всех них есть один метод getArray()
который возвращает вектор для постобработки.
если все эти указатели хранятся в каком-то списке (список пустых указателей говорит)
пока я перебираю список, есть ли способ выяснить, какой тип приведения указателя можно использовать?
Я понимаю, что это может быть решено с помощью иерархии классов и получения указанных классов из одного класса. Поскольку многое из этого является унаследованным кодом, можно ли сделать что-то наподобие того, что упоминается?
Безумная динамика не позволяет мне хранить указатели, это одна вещь, которую пробуют
Если getArray () всегда имеет одну и ту же сигнатуру (или достаточно похожую для приведения к одному и тому же типу) — вы можете создать иерархию классов для декоратор из утка типизированного унаследованные объекты / классы. Вы можете использовать производный от шаблона класс не-шаблонного интерфейса, чтобы обернуть его без особых усилий при наборе текста.
Что-то вроде этого (с более защитным кодированием, возможно, умными указателями на унаследованный объект и т. Д. И т. Д.):
class IDecorator {
public:
virtual std::vector<ubyte> GetArray() = 0;
};
template<typename TLegacyType>
class TDecorator : public IDecorator {
public:
TDecorator(const TLegacyType *ip_legacy_object)
: mp_legacy_object(ip_legacy_object) {}
std::vector<ubyte> GetArray() override {
return mp_legacy_object->GetArray();
}
private:
const TLegacyType *mp_legacy_object;
};
template<class R, class Op>
struct any_ptr {
void* ptr=0;
R(*f)( void* ) = 0;
R operate() const { return f(ptr); }
explicit operator bool() const { return ptr; }
template<class T>
T* as() const { return static_cast<T*>(ptr); }
any_ptr(any_ptr const&)=default;
any_ptr& operator=(any_ptr const&)=default;
any_ptr()=default;
template<class T>
any_ptr(T* p_in):ptr(p_in),
f( [](void* ptr)->R{ return Op{}( ptr ); } )
{}
};
any_ptr
поддерживает хранение любого указателя, который поддерживает Op
, где Op
тип объекта функции без сохранения состояния, возвращающий R
,
struct get_array_t{
template<class T>
auto operator()(T* t)const{ return t->getArray(); }
};
using any_ptr_get_array = any_ptr< std::vector<int>, get_array_t >;
сейчас any_ptr_get_array
может хранить указатель на любой тип, который поддерживает .getArray()
это возвращает vector<int>
,
Звонить getArray
:
void test(any_ptr_get_array ptr){
if(ptr){
auto vec = ptr.operation();
}
}
Эту технику можно назвать ручным стиранием типа с использованием шаблона, сгенерированного vtable.