Is it possible to implement Qt Application Plugin using a base and derived class?

283 Views Asked by At

Suppose I have the following toy interface:

class iTest{
  virtual ~iTest(void) = 0;
  virtual void doA(void) = 0;
  virtual void doB(void) = 0;
}

Q_DECLARE_INTERFACE(iTest, "somestring")

I'd like to implement this in two classes: Base and Derived.

class Base : public QObject, public iTest
{
  Q_OBJECT
  Q_PLUGIN_METADATA (IID "somestring")
  Q_INTERFACES(iTEST)
  explicit Base(QObject* parent=0);
  void doA(void); // do common thing all derived need do
  int data; // some data member all derived should have
}

class Derived: public Base
{
  Q_OBJECT
  Q_PLUGIN_METADATA (IID "somestring")
  Q_INTERFACES(iTEST)
  explicit Derived(QObject* parent = 0);
  void doB(); // do something custom dervived objects need do
}

My faulty reasoning tells me that this should work. An abstract base class for the plugin giving functionality for a part of the interface while the derived classes constitute the remainder of it. I can get this to compile, with some judicious removal of macros (the base class metadata macro). However, the plugins resulting won't load. So I assume there's something faulty in my reasoning which a more experience Qt developer or c++ developer could point out that I just can't see.

1

There are 1 best solutions below

1
On

I believe I've come up with a solution for this. As Alexander V mentioned above, the Q_ macros in the Base and Derived classes were conflicting with one another. The documentation states that only a single called to the Q_PLUGIN_METADATA macro can be in the code. What occurred to me is that the base class itself need not even be a Q_Object, it's just a container for functions. I, therefore, re-declared the classes as follows:

class Base: public iTest{
  void doA(void); // do something all derived should do
  int data; // data all derived should have
}

class Derived: public QObject, public Base{
  Q_OBJECT
  Q_PLUGIN_METADATA (IID "somestring")
  Q_INTERFACES(iTEST)  
  void doB(void): // custom to derived
}

Also, the interface needs a slight modification:

...
  virtual ~iTest(void){}
...

This is due to the fact that the destructor needs to be defined, and cannot be pure virtual. With these modifications, this structure seems to work in my application.