Search code examples
c++inheritancepthreadsvirtual

C++ Inheritance and Pthreads with Virtual Worker Functions


I have a class that I'm trying to implement as an abstract class to maximize code reuse. However, a major part of the commonality between the two derived classes lies in the fact that each has a consumer and producer thread. I'm wondering if I can have each static member function call a virtual member function that does all of the underlying work.

Basically, is the following code allowed or am I doing something super hacky, or will the compiler yell/scream at me?

// in AbstractClass.h
class AbstractClass {
  // some code here including constructors/destructors
 protected:
  virtual int Worker() = 0;  // derived class provides implementation
 private:
  static void* Thread(void* args);
};

// in AbstractClass.cpp
static void* AbstractClass::Thread(void* args) {
  AbstractClass myobject = static_cast<AbstractClass*>(args);
  myobject->Worker();
}

Basically I'm wondering if the derived class "worker" will ever be called this way? Note that p_thread_create() is called with passing in the Thread() function.

Thanks for the help as I try to improve my understanding of inheritance and virtual functions and how I can use it to maximize code reuse.


Solution

  • Yes the code looks fine and your assumptions are correct. The purpose of virtual functions is that the most derived version of a function will be called no matter which superclass signature the method is called on.

    Using pthreads and C++, the approach you are using is perfectly reasonable and not hackey. However, I would create the threads in a separate class which would contain the static class method. This would stop the threads from being mixed up in your derived classes.

    struct ThreadManager
    {
      ThreadManager(AbstractWorker* worker)
      {
         mWorker = worker;
         mThread = ThreadStart(threadFunc, this); /* made up thread code :) */
      }
      ~ThreadManager()
      {
         ThreadStop(mThread);
      }
    
      static void* threadFunc(void* args)
      {
         ThreadManager* manager = static_cast<ThreadManager*>(args);
         manager->mWorker->Work();
      }
    
      AbstractWorker* mWorker;
      Thread mThread;
    }
    

    Note that when using pthreads a static function is actually required.