首页 > 解决方案 > Spawning a thread in derived class in C++ with factory pattern

问题描述

I'm looking at using a factory pattern and spawning threads on instances.

Below is my code, and I get the following error:

error: invalid use of non-static member function ‘virtual void base::threadFunction()’
   75 |   thread t1(myClass1->threadFunction);
#include <memory>
#include <iostream>
#include <thread>

using namespace std;
enum classEnum
{
  class1Enum,
  class2Enum
};

class base
{
  public:
    base(classEnum classType)
    {
      this->classType = classType;
    }

    classEnum getClassEnum() { return classType; }
    virtual void threadFunction() = 0;

  private:
    classEnum classType;
};

class class1: public base
{
  public:
    class1() :
      base(class1Enum)
    {
    }

    void threadFunction()
    {
      cout << "Hello from class1\n";
      //call uniqueFunction using unique variables
    }
  private:
    //unique variable types and functions
};

class class2: public base
{
  public:
    class2() :
      base(class2Enum)
    {
    }

    void threadFunction()
    {
      cout << "Hello from class2\n";
      //call uniqueFunction using unique variables
    }
  private:
    //unique variable types and functions
};

class factory
{
  public:
    static std::shared_ptr<base> create(classEnum classType)
    {
      switch(classType)
      {
        case class1Enum:
          return make_shared<class1>();
        case class2Enum:
          return make_shared<class2>();
        default:
          return NULL;
      }
    }
};

int main()
{
  shared_ptr<base> myClass1 = factory::create(class1Enum);
  shared_ptr<base> myClass2 = factory::create(class2Enum);

  thread t1(myClass1->threadFunction);
  thread t2(myClass2->threadFunction);

  t1.join();
  t2.join();
  return 0;
}

Now, I see that the error says that I am using a non-static method, but changing the base to static means I can no longer access member variables and the derived functions aren't being called (which makes sense).

So how should I spawn these threads?

标签: c++multithreadingc++11factory

解决方案


Since those functions are non-static (i.e., they are called on objects), your threads need objects for them to call. Change this:

thread t1(myClass1->threadFunction);
thread t2(myClass2->threadFunction);

to this:

thread t1(&base::threadFunction, myClass1.get());
thread t2(&base::threadFunction, myClass2.get());

This tells the threads to call threadFunction on the passed objects.

Notice the change in the syntax (& and ::) and that we are calling the base versions - it's because we're passing base*, and virtual will do its thing. We can't force the threads to run any specific implementation (&class1:: or &class2::) because the .get() call could return a base pointer to a type that does not match those specified previously. This information is only available at runtime.


推荐阅读