There's nothing wrong with keeping a container of derived class observing pointers for direct and immediate access while keeping an overall base class container for management:
#include <vector>
#include "Animal.hpp"
#include "Snake.hpp"
#include "Spider.hpp"
#include "Mosquito.hpp"
#include "IVenomous.hpp"
#include "IFlyer.hpp"
std::vector<std::unique_ptr<Animal>> m_Animals{};
std::vector<IVenomous*> m_VenomousAnimals{};
std::vector<IFlyer*> m_FlyingAnimals{};
void RegisterNewSnake() {
auto newSnake = std::unique_ptr<Snake>make_unique<Snake>(isVenomous);
auto* ptr = newSnake.get();
m_Animals.emplace_back(std::move(newSnake));
m_VenomousAnimals.push_back(ptr);
}
void RegisterNewSpider(bool isVenomous) {
auto newSpider = std::unique_ptr<Spider>make_unique<Spider>(isVenomous);
auto* ptr = newSpider.get();
m_Animals.emplace_back(std::move(newSpider));
m_VenomousAnimals.push_back(ptr);
}
void RegisterNewMosquito() {
auto newMosquito = std::unique_ptr<Mosquito>make_unique<Mosquito>();
auto* ptr = newMosquito.get();
m_Animals.emplace_back(std::move(newMosquito));
m_FlyingAnimals.push_back(ptr);
}
void RegisterNewOstrich() {
auto newOstrich = std::unique_ptr<Ostrich>make_unique<Ostrich>();
m_Animals.emplace_back(std::move(newOstrich));
}
std::vector<IVenomous*> GetAllVenomousAnimals() {
return m_VenomousAnimals;
}
std::vector<IFlyer*> GetAllFlyingAnimals() {
return m_FlyingAnimals;
}
void RemoveVenomousAnimal(IVenomous* ptr) {
m_VenomousAnimals.erase(std::remove(std::begin(m_VenomousAnimals), std::end(m_VenomousAnimals), ptr), std::end(m_venomousAnimals));
m_Animals.erase(std::remove_if(std::begin(m_Animals), std::end(m_Animals), [ptr](const auto& a){ a.get() == ptr; }), std::end(m_Animals));
}
//Similar for RemoveSnake
//Similar for RemoveSpider
void RemoveFlyer(IFlyer* ptr) {
m_FlyingAnimals.erase(std::remove(std::begin(m_FlyingAnimals), std::end(m_FlyingAnimals), ptr), std::end(m_FlyingAnimals));
m_Animals.erase(std::remove_if(std::begin(m_Animals), std::end(m_Animals), [ptr](const auto& a){ a.get() == ptr; }), std::end(m_Animals));
}
//Similar for RemoveMosquito
```