Это может быть невозможно, поэтому альтернативных решений проблемы также будет достаточно
У меня есть список действий, которые я хочу отслеживать
class Activity {
public:
virtual void DoSomething() = 0 ;
};
std::vector<Activity*> activities;
Допустим, у меня естьследующие дочерние классы
class GraphicsActivity : public Activity {
public:
virtual void DoSomething() { }
void HandleGraphics() { /* do some management */; }
};
class UpdateActivity : public Activity {
public:
virtual void DoSomething() { ; }
};
class PhysicsActivity : public Activity {
public:
virtual void DoSomething() { ; }
};
Теперь предположим, что мы хотим извлечь одно из этих действий из нашего списка.Функция выглядела бы как
template<typename T> T* GetActivity() {
for(int i = 0; i < activities.size(); i++) {
T* cast = dynamic_cast<T*>(activities[i]);
if(cast != nullptr) {
return cast;
}
}
return nullptr;
}
Мы могли бы использовать ее так:
activities.push_back(new GraphicsActivity());
activities.push_back(new PhysicsActivity ());
activities.push_back(new UpdateActivity ());
GraphicsActivity* g = GetActivity<GraphicsActivity>();
Допустим, у нас есть еще одно действие, которому нужно использовать полиморфизм для использования некоторых методов базового класса.
class 3DGraphicsActivity : public GraphicsActivity {
public:
void Handle3DGraphics() {
/* Utilize base class function */
this->HandleGraphics();
/* do some extra work */
}
};
Теперь мы хотим получить ту же активность, что и раньше, и наш список теперь выглядит в следующем порядке следующим образом:
activities.push_back(new GraphicsActivity3D());
activities.push_back(new GraphicsActivity());
activities.push_back(new PhysicsActivity ());
activities.push_back(new UpdateActivity ());
Но нам нужен оригинальный тип GraphicsActivity
, поэтому мы идем, чтобы получить его:
GraphicsActivity* g = GetActivity<GraphicsActivity>();
Мы фактически получим указатель на первую запись в списке, потому что она разделяет базовый класс типа GraphicsActivity
.
В этом и заключается проблема: как я могу написать такой список, элементы которого должны иметь общий базовый класс Activity
, а также иметь возможность получить точный тип из списка, не попадая в ловушку dynamic_cast
, которую мытолько что объяснил?