我想实现非模板化的类,就像评论的那样。未注释的类将导致编译错误error: invalid use of non-static member function 'virtual void BaseThread::worker()
#include <iostream>
#include <thread>
/*
class BaseThread
{
public:
void start()
{
// error: invalid use of non-static member function 'virtual void BaseThread::worker()'
thread_ = std::thread(worker);
}
private:
virtual void worker() = 0;
std::thread thread_;
};
*/
template <typename Derived>
class BaseThread
{
public:
void start()
{
thread_ = std::thread(Derived::worker);
}
private:
virtual void worker() = 0;
std::thread thread_;
};
class DerivedThread : public BaseThread<DerivedThread>
{
private:
void worker()
{
std::cout << "Derived\n";
}
};
int main()
{
DerivedThread dt;
}发布于 2020-02-14 22:18:49
要点很简单:您将一个成员函数传递给一个线程对象,而不是一个可以调用该函数的对象。
模板似乎只解决了这个问题,因为您没有实例化它。一旦你这样做了,同样的问题就会再次出现。
您可以通过将实例作为参数传递来解决此问题:
thread_ = std::thread(&BaseThread::worker, this);此外,您必须通过适当的运算符和类范围解析来获取成员函数指针。
附注:当你有一个虚拟函数时,你应该考虑添加一个虚拟析构函数,否则通过指向基类的指针删除派生类将会失败。
也不要忘了在析构函数中加入线程(或者你觉得合适的任何地方)。
发布于 2020-02-14 22:18:37
为什么这个不能编译?重点是你根本没有得到正确的语法,仅此而已。不能在没有对象的情况下调用成员函数。将它们传递给std::thread的一种简单方法如下:
std::thread th{&ThreadBase::worker, this}然而,您选择了一个不幸的抽象,那就是首先创建一个“线程”类,这需要您从派生。不要这样做,因为它混合了两个关注点,即被调用的代码和线程。在某种程度上,这类似于创建一个文件基类,从这个基类派生出不同的文件格式。这种有缺陷的方法的标志是,在这两种情况下,线程或文件的实例都不是线程或文件!想想看,std::thread的实例不是线程,std::fstream的实例也不是文件。相反,这些对象是可用于与线程或文件交互的对象,类似于数据库客户端用于与数据库交互的方式。
总之,不要编写从BaseThread派生的类,只需编写执行某些操作的类即可。不要让这个类担心它的代码是否在线程中被调用。如果你想这样做,只需使用你已经在幕后做过的std::thread即可。
发布于 2020-02-14 22:23:42
更简单和非模板化的实现可以是这样的。
#include <thread>
#include <iostream>
#include <functional>
class BaseThread
{
public:
virtual ~BaseThread() { thread_.join(); }
void start()
{
thread_ = std::thread( &BaseThread::worker , this );
}
protected:
virtual void worker() = 0;
private:
std::thread thread_;
};
class DerivedThread : public BaseThread
{
protected:
void worker() override
{
std::cout << "Derived\n";
}
};
int main()
{
DerivedThread dt;
DerivedThread dt2;
dt.start();
dt2.start();
std::this_thread::sleep_for( std::chrono::seconds { 5 } );
}https://stackoverflow.com/questions/60227836
复制相似问题