【问题标题】:Thread creation on a derived class method results in error在派生类方法上创建线程会导致错误
【发布时间】:2021-11-09 05:37:12
【问题描述】:

我有一个抽象类如下:

    class AbstractClass : public std::enable_shared_from_this<AbstractClass> {
    public:
        virtual ~AbstractClass() = default;

        virtual bool Start() = 0; 
        virtual void Stop() = 0;
    };

这是派生类:

    class DerivedClass : public AbstractClass {
    public:
        bool Start() override;
        void Stop() override;
    }

我正在尝试在另一个文件中创建派生类的对象和派生类方法的线程:

    // Create object
    derivedClass_.reset(...);

    //Start a thread for the derived class method
    std::unique_ptr<boost::thread> derivedClassThread_;

    derivedClassThread_.reset(new boost::thread(std::bind(&DerivedClass::Start, 
    derivedClass_)));

当我编译这个时,我得到了一些奇怪的错误:

错误:'class std::result_of'

有人可以帮我吗?

【问题讨论】:

  • 很难确定这是否会为您解决问题,但这肯定会更有意义:derivedClassThread_ = std::make_shared&lt;boost::thread&gt;([derived_class_]{ derived_class_-&gt;Start(); });
  • 嗨@Frank,感谢您的回复。这是我编译时得到的:错误:捕获非变量 'derived_class_'derivedClassThread_ = std::make_shared<:thread>([derived_class_]{ derived_class_->Start(); });错误:没有为这个 lambda 函数捕获“this” dderivedClassThread_ = std::make_shared<:thread>([derived_class_]{ derived_class_->Start(); });

标签: c++ boost abstract-class virtual-functions


【解决方案1】:

您的代码不是独立的,所以我们必须猜测。以下是我认为你会拥有/想要的:

Live On Coliru

#include <boost/thread.hpp>
#include <memory>
#include <iostream>

class AbstractClass : public std::enable_shared_from_this<AbstractClass> {
  public:
    virtual ~AbstractClass() = default;

    virtual bool Start() = 0;
    virtual void Stop()  = 0;
};

class DerivedClass : public AbstractClass {
  public:
    bool Start() override {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
        return true;
    }
    void Stop() override { }
};

int main()
{
    // Create object
    std::shared_ptr<AbstractClass> derivedClass_ =
        std::make_shared<DerivedClass>();

    // Start a thread for the derived class method
    auto derivedClassThread_ = std::make_unique<boost::thread>(
        [derivedClass_] { derivedClass_->Start(); });

    if (derivedClassThread_ && derivedClassThread_->joinable())
        derivedClassThread_->join();

    derivedClassThread_ = std::make_unique<boost::thread>(
        std::bind(&AbstractClass::Start, derivedClass_));

    if (derivedClassThread_ && derivedClassThread_->joinable())
        derivedClassThread_->join();
}

编译没有问题。

更新以回应评论,表明您实际上可以使用 std::bind 做到这一点。

打印:

virtual bool DerivedClass::Start()
virtual bool DerivedClass::Start()

【讨论】:

  • “使用std::bind 需要获取任何具体方法覆盖的地址”——会吗? IIRC 成员函数指针在调用时可以执行虚拟调度。
  • @Quentin 你可以试试。你将如何指出你想要的语义? &amp;AbstractClass::Start 看起来很奇怪(因为它是纯虚拟的),而且当 &amp;DerivedClass::Startnot 返回去虚拟化的 void(DerivedClass::*)() 时也会很奇怪 - 如果不是,该语言将如何支持获得它指针?
  • @Quentin 我已经纠正了! coliru.stacked-crooked.com/a/c1fa2ef9ba476f10 事实证明,&amp;DerivedClass::Start 并没有像我预期的那样去虚拟化。 (让我之前的问题评论悬而未决,但修复了答案)
  • 非常感谢@sehe。这有帮助! :)
猜你喜欢
  • 2011-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
  • 1970-01-01
相关资源
最近更新 更多