How to check the type of a derived class within a plugin/toolkit framework

Viewed 7

I'm seeking advice on how do I implement a copy constructor of an unknown derived type?

Consider the following:

I'm designing an app that will allow other developers to write their own plugins that conform to a virtual interface, Vehicle.

Developers may wish to create Car, Tank, or Motorbike plugins.

Class Tank : public Vehicle ...
Class Car : public Vehicle ...

I want the app to make copies of the derived classes; but these classes are unknown to my app at compile time because they have been dynamically loaded via a plugin system by the end-user at runtime.

Vehicle * newCopyOfVehicle = new Vehicle(myExistingCarClass); // Only copies the base class, not the derived class.

It seems to me that I should ask the class to make a copy of itself and report back to the app with an Vehicle interface?

Is this a good idea?

1 Answers

I'm answering my own question because I think I found a good solution while writing a good question.

The Car class is integral to the app and thus I had not made it a plugin yet, but just coded it as a regular class within my app during development and testing - This was a mistake!

Thus the following code worked...

Vehicle * newVehicle = new Car()

...but another part of my app failed while making copies of derived types for which I didn't know the exact type.

Vehicle * copyOfVehicle = new Vehicle(newVehicle); // Only copies the base class, not the derived class.

Therefore, when creating new objects or creating copies of existing objects I should code something like this instead:

Vehicle* _newVehicle;
std::wstring wstrType = L"Car";
for (std::vector<IPlugIn*>::iterator plugin = m_PlugIns.begin(); plugin != m_PlugIns.end(); ++plugin)
{
    if ((*plugin)->SupportsVehicle(wstrType))
        _newVehicle = (*plugin)->CreateVehicle();
}

(Ignore the hard-coded variable containing 'Car' as this will be replaced by something generic later)

Test code for plugin...

class CarFactoryPlugIn : public IPlugIn
{
public:
    CarFactoryPlugIn();
    virtual ~CarFactoryPlugIn();
    virtual bool SupportsVehicle(const std::wstring& derivedTypeName);
    virtual Vehicle* CreateVehicle(void);
private:
};

CarFactoryPlugIn::CarFactoryPlugIn() {}

CarFactoryPlugIn::~CarFactoryPlugIn() {}

bool CarFactoryPlugIn::SupportsVehicle(const std::wstring& derivedTypeName) {
    return (derivedTypeName == L"Car");
}

Vehicle* CarFactoryPlugIn::CreateVehicle(void) {
    return new Car();
}
Related