【发布时间】:2016-10-15 09:46:03
【问题描述】:
我写了这个简单的例子来了解发生了什么 我希望所有逻辑都在基类中实现,并在派生类中派生特定方法,所以:
#include <thread>
#include <atomic>
#include <chrono>
#include <iostream>
class base
{
public:
base() : stop(false) {}
virtual ~base()
{
std::cout << "Destructor base\n";
if( handle.joinable() )
{
stop = true;
handle.join();
}
}
void runThread() { handle = std::thread( worker, this ); }
virtual void stopThread() { std::cout << "Base stopThread\n"; }
protected:
std::atomic<bool> stop;
std::thread handle;
static void worker( base *me )
{
while( me->stop == false )
{
std::cout << "Working\n";
me->stopThread(); // this one in called as derived
std::this_thread::sleep_for( std::chrono::seconds(1) );
}
me->stopThread(); // this one is called as base
}
};
class derived : public base
{
public:
~derived()
{
std::cout << "Destructor derived\n";
}
private:
void stopThread() { std::cout << "derived stopThread\n"; }
};
int main()
{
derived der;
der.runThread();
std::this_thread::sleep_for( std::chrono::seconds(3) );
}
结果:
Working
derived stopThread
Working
derived stopThread
Working
derived stopThread
Destructor derived
Destructor base
Base stopThread <-- hmmm
所以除了基本析构函数之外一切都正常 - 它调用 base::stopThread。为什么会这样?如果我把它变成纯虚拟的,我会得到一个例外。
我可以通过将析构函数移动到派生类来解决这个问题,但这不清楚,因为我希望所有逻辑都在基类中实现。
我哪里错了?
谢谢
【问题讨论】:
-
与线程无关:对象在其析构函数中的动态类型是其静态类型,因为任何派生部分都已被销毁。
-
顺便说一句,纯虚函数给你一个例外的事实应该已经暗示了你。
-
附带说明,规则因语言而异,因此如果你想做一些高级的事情,你必须学习你的语言规则。
-
这种设计在任何语言中都不好;
base代表什么?抽象是什么? -
@curiousguy 一些具有轮询逻辑和接口的设备类,派生的是不同的版本和型号。当软件停止时,它应该被正确禁用
标签: c++ multithreading polymorphism destructor virtual-functions