Call method implemented in derived classes by iterating the base class vector

Viewed 47

I have a C++ design problem regarding the base class and the derived class. Here is the code looks like:

class BaseClass:
{
  public:
     BaseClass();
     virtual ~BaseClass();
     //...Some basic functions for the derived Classes
     void write_data(void* data);
};

class DerivedClass1 : BaseClass
{
  public:
     DerivedClass1(){}
     ~DerivedClass1() override{}
     void method(Type1 data);
}

class DerivedClass2 : BaseClass
{
  public:
     DerivedClass2(){}
     ~DerivedClass2() override{}
     void method(Type2 data);
}
// There are hundreds of auto-created derived classes
.....

The class that instantiates the derived classes uses a vector to store the instantiated derived classes:

std::vector<std::unique_ptr<BaseClass>> m_factory_vector;

The function that stores the classes is:

template<typname Type>
void fun(Type& data)
{
   std::unique_ptr<BaseClass> base= std::make_unique<Type>(*file_);
   base.get()->method(data);
   m_factory_vector.push_back(base);
}

The reason that using the template is due to the number of functions call the fun is unknown.

Now I would like to iterate through the vector and call the method in the derived classes again. Because the methods write a different type of data into the HDF5 file by collecting the data in a buffer(size 100, but the total size is unknown), but there is some data remaining in the collected batch that I would like to flush when the program is ended. Here is the problem I am having, I wish I can do it like:

for(hsize_t i=0;i<m_factory_vector.size();i++)
{
   m_factory_vector[i]->method({});
}

But I know the problem is the method is not in the BaseClass but in the derived classes. But the method in derived classes has different types of input parameters that I may not able to declare virtual void method() in BaseClass. However, I still want to have something like this so that I can call flush those data into the database without losing the data.

1 Answers

Without reworking your design, you might use dynamic_cast:

for (hsize_t i=0;i<m_factory_vector.size();i++)
{
   if (auto* p = dynamic_cast<DerivedClass1>(m_factory_vector[i]->get()))
       p->method({});
   else if (auto* p = dynamic_cast<DerivedClass2>(m_factory_vector[i]->get()))
       p->method({});
   // ...
}
Related