【问题标题】:Creating thread in the base class which run a method from the subclasses在基类中创建从子类运行方法的线程
【发布时间】:2012-10-13 22:09:19
【问题描述】:

我不知道这是否可能,但我有一个想法,即创建一个抽象类来使用 WinAPI 创建线程。该类将被定义在线程中执行的函数的类继承。

我有两个班级:

class XYZ{
//...

class ABC: public XYZ{
//...

我有一个构造

ABC::ABC()
{
    addThread(this,1);
}

addThread 在 XYZ 类中定义:

void addThread(void* self, int a)
{
    DWORD ThreadID;
    THREAD_DATA *threadData;
    threadData->self = self;
    threadData->thread_id = a;
    CreateThread(NULL, 0, createThread, threadData, 0, &ThreadID);
}

如您所见,我正在创建一个包含两个字段的结构:超类的对象和线程数(因此该方法可以知道使用哪些数据)。

结构如下:

typedef struct _THREAD_DATA {
void*       self;
int     thread_id;
} THREAD_DATA;

XYZ类的静态方法中的createThread:

static DWORD WINAPI createThread(void* _threadData)
{
    THREAD_DATA* threadData = (THREAD_DATA*) _threadData;
    return threadData->self->execute(threadData->thread_id);
}

这里是一切都出错的地方。 我的 VSC++ 2010 在静态方法主体的第二行中强调了第一个单词“threadDataself”。 编译后出现错误:

'->execute' 的左边必须指向类/结构/联合/泛型类型

我不知道如何解决它。我使用这些链接编写了这段代码: http://goo.gl/7VYC3 & http://goo.gl/ETfe7

execute 方法在 XYZ 类中声明为:

virtual DWORD execute(int i);

然后在ABC类中定义为

DWORD ABC::execute(int i){
//...

谁能帮帮我?我将不胜感激任何提示如何使它工作。

【问题讨论】:

  • 你在哪里定义threadDataself?你的意思是threadData->self->execute?
  • 是的,这是一个错误。我编辑了这个问题。对不起这个问题。 PS:这是有错误的那一行。

标签: c++ multithreading winapi object inheritance


【解决方案1】:

"self" 被定义为一个空指针,你试图在它上面调用"execute" 方法,它不存在。您需要将 self 的类型更改为包含方法“execute”的基类。

像这样:

typedef struct _THREAD_DATA {
    XYZ*       self;
    int     thread_id;
} THREAD_DATA;

当您在这里尝试以多态方式调用被覆盖的方法时,您必须确保调用该方法的对象的类型是基类类型。不能使用 void 指针。

【讨论】:

    【解决方案2】:

    一个明显的错误需要你解决:

    THREAD_DATA *threadData;
    threadData->self = self;
    threadData->thread_id = a;
    

    这里的threadData是一个没有赋值的指针,然后你用is作为一个有效的指针。您需要将其更改为

    THREAD_DATA *threadData = new THREAD_DATA();
    

    并以某种方式管理其生命周期,即。在 thred 函数中删除它。

    【讨论】:

    • 哦,是的,我完全错过了。我建议只取出 * 并将 threadData 通过引用传递给 CreateThread,但很好!
    • 指针在这里很重要,如果您将其删除,那么线程函数将读取实际上不存在的 thread_data。没有指针 threadData 是在堆栈上创建的。
    • 感谢您的帮助。一切都差不多了,但我仍然有一个问题。编译项目后,我从链接器收到关于未解析标识符 XYZ::execute(); 的错误;我可以质疑编译器正在尝试从基类调用该方法。但我想从超类中调用该方法。这甚至可能吗?
    • 替换虚拟双字执行(int i);在 XYZ 中,使用虚拟 DWORD 执行(int i)= 0;或使用虚拟 DWORD 执行(int i){return 0;}。
    • 别忘了在 XYZ 中添加虚拟析构函数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 2012-07-23
    • 1970-01-01
    相关资源
    最近更新 更多