C++ C++;虚析构函数导致调用基方法
我写了这个简单的例子来了解发生了什么 我希望在基类中实现所有逻辑,在派生类中实现派生的特定方法,因此:C++ C++;虚析构函数导致调用基方法,c++,multithreading,polymorphism,destructor,virtual-functions,C++,Multithreading,Polymorphism,Destructor,Virtual Functions,我写了这个简单的例子来了解发生了什么 我希望在基类中实现所有逻辑,在派生类中实现派生的特定方法,因此: #include <thread> #include <atomic> #include <chrono> #include <iostream> class base { public: base() : stop(false) {} virtual ~base() { std::cout <&
#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) );
}
#包括
#包括
#包括
#包括
阶级基础
{
公众:
base():停止(false){}
虚拟~base()
{
std::cout stopThread();//这个被称为基
}
};
派生类:公共基
{
公众:
~derived()
{
std::cout虚拟方法不会分派给构造函数或析构函数中派生最多的实现。这是因为在调用base
的析构函数时,派生的
实例已被销毁
更正式地说,正如昆廷在评论中所说,虚拟方法分派到构造函数或析构函数内的实例的静态类型。虚拟方法不会分派到构造函数或析构函数内最派生的实现。这是因为在调用base
的析构函数时d派生的
实例已被销毁
更正式地说,正如昆廷在评论中所说,虚拟方法将分派到构造函数或析构函数内实例的静态类型。与线程无关:析构函数内对象的动态类型是其静态类型,因为任何派生部分都已销毁。顺便说一句,纯虚拟函数给你一个例外,我应该提醒你。作为旁注,规则因语言而异,因此如果你想做一些高级工作,你必须学习语言的规则。这种设计在任何语言中都是糟糕的;
base
代表什么?抽象是什么?@curiousguy一些带有轮询逻辑和接口的设备类,derived是不同的版本和模型。当软件停止时,应该正确地禁用它与线程无关:其析构函数中对象的动态类型是其静态类型,因为任何派生部分都已被销毁。顺便说一句,纯虚拟函数给了您一个异常的事实应该已经暗示了您。作为旁注,规则因语言而异,因此如果你想做一些高级工作,就必须学习语言的规则。这种设计在任何语言中都不好;base
代表什么?抽象是什么?@curiousguy一些带有轮询逻辑和接口的设备类,派生的是不同的版本和型号。软件停止时应该正确禁用它“原因是,在调用base的析构函数时,派生实例已经被销毁。”为了清楚起见,您可以添加以下内容:“相反,当调用base
的构造函数时,派生的部分还没有被构造。所以解决这个问题的唯一方法是将析构函数移到派生类?@FedorKryukov,你现在可能需要重新考虑你的设计,知道这一点(有时很不方便)关于构造函数/析构函数的非polymophic调用的事实。无论如何,在析构函数中加入线程并不一定是最好的主意。@FedorKryukov-您可以将所有停止逻辑移到基类中,这样您就可以从析构函数调用它了。@Sean在我的项目中这是不可能的,因为派生类实现了各种硬件设备具有不同的停止命令,因此我将从构造它们的对象进行连接。谢谢!“原因是,在调用base的析构函数时,派生实例已经被销毁。”为了清晰起见,我认为您可以添加以下内容:“相反,当调用base
的构造函数时,派生的部分还没有被构造。所以解决这个问题的唯一方法是将析构函数移到派生类?@FedorKryukov,你现在可能需要重新考虑你的设计,知道这一点(有时很不方便)关于构造函数/析构函数的非polymophic调用的事实。无论如何,在析构函数中加入线程并不一定是最好的主意。@FedorKryukov-您可以将所有停止逻辑移到基类中,这样您就可以从析构函数调用它了。@Sean在我的项目中这是不可能的,因为派生类实现了各种硬件设备具有不同的停止命令,因此我将从构造它们的对象进行连接。谢谢!
Working
derived stopThread
Working
derived stopThread
Working
derived stopThread
Destructor derived
Destructor base
Base stopThread <-- hmmm