使用工厂模式在 C++ 的派生 class 中生成一个线程

Spawning a thread in derived class in C++ with factory pattern

我正在考虑使用工厂模式并在实例上生成线程。

下面是我的代码,我收到以下错误:

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;
}

现在,我看到错误说我正在使用非静态方法,但是将基数更改为静态意味着我无法再访问成员变量并且派生函数不会被调用(这是有道理的).

那么我应该如何生成这些线程?

由于这些函数是非静态的(即,它们在 objects 上调用),您的线程需要对象才能调用。改变这个:

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

对此:

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

这告诉线程调用threadFunctionon传递的对象

请注意语法的变化(&::),我们正在调用 base 版本 - 这是因为我们要传递 base*,并且virtual 会做它的事情。我们不能强制线程运行任何特定的实现(&class1::&class2::)因为.get()调用可能return 指向与先前指定的类型不匹配的类型的基指针。此信息仅在 运行 时间可用。