В настоящее время я храню указатели разных типов в векторе.Чтобы архивировать это, я реализовал шаблон класса «Store», который является производным от неклассового шаблона «IStore».Мой вектор наконец хранит указатели на «IStore».В коде:
class IStore
{
public:
IStore() = default;
virtual ~IStore() = default;
virtual void call() = 0;
// ... other virtual methods
};
template<typename T>
class Store : public IStore
{
public:
Store() = default;
virtual ~Store() = default;
virtual void call() override;
// ... other virtual methods
private:
T* m_object = nullptr;
}
И в моем основном классе, который содержит вектор:
class Main
{
public:
template<typename T>
void registerObject(T* ptr);
template<typename T>
void callObjects();
// ... other methods
private:
std::vector<IStore*> m_storedObjects;
};
Пока что структура текущего класса.Чтобы описать проблему, мне нужно представить следующие три примера структур:
struct A {}
struct B : public A {}
struct C : {}
Другие классы должны вызывать метод Main :: registerObject с указателями на объекты типов A, B или C.Этот метод затем создаст новый магазин , магазин соответственно.Сохраните объект класса шаблона и вставьте указатель на этот объект в m_storedObjects.
Теперь начинается сложная часть: метод Main :: callObjects должен вызываться другими классами с аргументом шаблона, таким как Main :: callObjects ().Это должно выполнить итерацию через m_storedObjects и вызвать метод IStore :: call для каждого объекта, который относится к типу B или к которому относится тип B.
Например:
Main::registerObject<A>(obj1);
Main::registerObject<B>(obj2);
Main::registerObject<C>(obj3);
Main::callObjects<B>();
Следует вызватьobj1 и obj2, но не obj3, потому что C не является B, а B не получен из C.
Мои подходы в Main :: callObjects были следующими: 1. Выполнить dynamic_cast и проверить на nullptr, например:
for(auto store : m_storedObjects)
{
Store<T>* base = dynamic_cast<Store<T>*>(store);
if(base)
{
// ...
}
}
, который будет работать только для тех же классов, а не производных классов, поскольку Store не является производным от Store .2. Чтобы переписать оператор приведения в IStore и Store, чтобы я мог указать, что Store должен быть преобразуемым, когда аргумент шаблона является преобразуемым.Например в Store:
template<typename C>
operator Store<C>*()
{
if(std::is_convertible<T, C>::value)
{
return this;
}
else
{
return nullptr;
}
}
Но этот метод никогда не вызывается.
У кого-нибудь есть решение этой проблемы?Извините за длинный пост, но я думал, что больше кода будет лучше понять проблему.В любом случае спасибо за вашу помощь:)