Mar*_*ant 0 c++ windows polymorphism inheritance multithreading
我有以下代码:
#include <windows.h>
#include <iostream>
static DWORD __stdcall startThread(void *);
class BaseClass {
private:
void threadLoop() {
// stuff ...
std::cout << someStuff() << std::endl;
// stuff ...
}
protected:
HANDLE handle;
virtual int someStuff() {
return 1;
}
public:
friend DWORD __stdcall startThread(void *);
BaseClass() {
handle = 0;
};
void start() {
handle = CreateThread(NULL, 0, startThread, this, 0, NULL);
}
~BaseClass() {
if(handle != 0) {
WaitForSingleObject(handle, INFINITE);
CloseHandle(handle);
}
}
// stuff
};
static DWORD __stdcall startThread(void *obj_) {
BaseClass *obj = static_cast<BaseClass *>(obj_);
obj->threadLoop();
return 0;
}
class DerivedClass : public BaseClass {
public:
virtual int someStuff() {
return 2;
};
};
int main() {
BaseClass base;
base.start();
DerivedClass derived;
derived.start();
}
Run Code Online (Sandbox Code Playgroud)
每个实例都使用WINAPI和辅助函数创建一个线程,该函数startThread将调用委托给threadLoop创建线程的对象的方法.现在问题是threadLoop调用另一个虚方法,但是如果我使用virual方法的其他实现创建派生类,则多态性似乎不起作用.
为什么?我怎样才能解决这个问题?
编辑:我更新了代码,因此线程不会在构造函数中启动.
在构建派生对象之前,您将启动该线程.这是未定义的行为(因为您仍然可以在创建线程中执行代码时访问新线程中的对象).你必须分开构造和启动线程.
编辑:
处理此类问题的一种方法:
class Threadable
{
public:
virtual Threadable() {}
virtual run() = 0;
};
DWORD __stdcall startThread( void* object )
{
static_cast<Threadable*>( object )->run();
}
class Thread
{
std::auto_ptr<Threadable> myThread;
HANDLE myHandle;
public:
Thread( std::auto_ptr<Threadable> thread )
: myThread( thread )
, myHandle( CreateThread( NULL, 0, startThread, myThread.get(), 0, NULL ) )
{
}
~Thread()
{
if ( myHandle != NULL ) {
WaitForSingleObject( myHandle, INFINITE );
CloseHandle( myHandle );
}
}
};
Run Code Online (Sandbox Code Playgroud)
然后得到你的,BaseClass并DerivedClass从中
Threadable调用它们:
Thread base( std::auto_ptr<Threadable>( new BaseClass ) );
Thread derived( std::auto_ptr<Threadable>( new DerivedClass ) );
Run Code Online (Sandbox Code Playgroud)
这并不完美(我不喜欢在析构函数中或多或少地无限制等待),但它应该足以开始.(模拟上面代码中的任何拼写错误 - 我没有测试过它.)