c++ - 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?
解决方案
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.
推荐阅读
- snowflake-cloud-data-platform - 我可以让 Snowflake 从所有 CSV 列和第一行作为标题创建阶段吗?
- javascript - Mongodb .find() 结果相反
- reactjs - 如何控制地图中的多个输入对象值
- azure - 无法访问安装在 Azure ML 中的 python 包
- bash - 如何从用户那里获取符号来格式化模式
- r - 使用 randomForest 但说不能处理超过 53 个类别错误
- python - Python 中的什么价值等于一切?
- typescript - Typescript 只生成“export {};” 在 d.ts 文件中
- google-apps-script - Google 表格/应用程序脚本 - 一起添加重复数据 - 如果 Col A 和 Col B 相同
- javascript - 从 2 个不同的属性获取 MySql 表中的项目