可杀死线程类中的编译错误
Posted
技术标签:
【中文标题】可杀死线程类中的编译错误【英文标题】:compilation error in killable thread class 【发布时间】:2018-04-14 11:54:54 【问题描述】:我正在尝试设计一个派生自 std::thread 的 killable_thread 类。
该类应该有一个名为 die() 的成员,可以调用该成员来终止线程。
我的first attempt忽略了资源泄露的问题。它只是尝试调用析构函数,但没有编译:
/** killable_thread
A class that inherits the thread class to provide a kill() operation.
version 1.0 : only kills the thread. Ignores resources.
**/
#ifndef KILLABLE_THREAD
#define KILLABLE_THREAD
#include <thread> /// thread
#include <iostream> /// cout, endl
struct killable_thread : std::thread
/// inherit the thread class' constructor
/// [CPL], $20.3.5.1
using std::thread::thread;
using std::thread::operator=;
~killable_thread()
void die()
~killable_thread();
;
void f();
int main()
killable_thread kt f;
kt.die();
std::cout << "OK" << std::endl;
void f()
#endif /// KILLABLE_THREAD
编译错误为:
main.cpp: In member function 'void killable_thread::die()':
main.cpp:28:7: error: no match for 'operator~' (operand type is 'killable_thread')
~killable_thread();
^~~~~~~~~~~~~~~~~~
我应该怎么做?
【问题讨论】:
从其成员函数中调用对象的析构函数是有风险的 - 为什么需要这样做? 好吧,我还能如何终止线程? 你不能。在 C++ 中杀死线程的唯一类型安全是线程抛出异常以展开其所有范围,并从原始线程函数返回。此外,这与调用某个对象的析构函数完全无关。std::thread
只是一个对象。在这方面与std::cout
没有什么不同。唯一不同的是它有一个执行线程链接到它。并且指定如果在线程仍在运行时销毁它,整个程序将中止。线程不能以这种方式工作。
this->~killable_thread();
或 (*this).~killable_thread();
会帮助编译器。
是的。但是“终止”并不意味着“调用你自己的析构函数”。这意味着从原始线程函数返回。正如我所写,执行线程和std::thread
对象并不相同。事实上,一个线程不可能调用它自己的析构函数。如果可连接线程在其std::thread
析构函数被调用时仍在运行,则整个程序终止;并且线程仍然必须运行才能调用其析构函数。并在其执行线程被分离后调用std::thread
的析构函数,完全没有完成任何事情。
【参考方案1】:
~killable_thread();
编译器将其解释为 将一元 operator~
应用于使用默认构造函数 killable_thread()
创建的临时对象。要像方法一样调用析构函数,您应该像下面这样调用它:
this->~killable_thread();
或
(*this).~killable_thread();
【讨论】:
【参考方案2】:您可能需要添加“this”关键字:
this->~killable_thread();
还有一种写法:
delete this;
但是如上所述,不建议在方法中调用析构函数
【讨论】:
delete this
也有未定义的行为,除非当前对象 (*this
) 是使用运算符 new
创建的以上是关于可杀死线程类中的编译错误的主要内容,如果未能解决你的问题,请参考以下文章