【问题标题】:How to create a thread by a child member function如何通过子成员函数创建线程
【发布时间】:2019-07-25 04:09:40
【问题描述】:

我有一个IBase 课程和一个Child 课程。我需要在不同的子类中调用不同的proc 函数。我不确定下面哪种形式实际上是正确的,也许两者都不是 XD。

  • 表格 1:我不希望我的 IBase 有任何非虚拟功能。
  • 表格 2:&IBase::proc 有一个奇怪的表达方式可能会引起一些误解。
class IBase
{
public:
    virtual void proc() = 0;

    auto createBind()
    {
        return bind(&IBase::proc, this);
    }
};
class Child :public IBase
{
public:
    void proc() override
    {
        cout << "Hello World" << endl;
    }
};
int main()
{
    IBase* pointer = new Child;

        //form 1
    thread th(pointer->createBind());
    th.join();

        //form 2
    thread th2(&IBase::proc, pointer);
    th2.join();

    cout << "Finish" << endl;
    return 0;
}

我想知道你们如何在实际项目中解决这种情况。

【问题讨论】:

  • (这是特定于我处理的代码而不是一般规则)通常接口说“IParent”只包含虚拟/纯虚拟函数的声明说(“virtualFunc”)。然后从接口类派生类,比如 DeriveClass1 和 DeriveClass2,它们有自己的 'virtualFunc' 实现。现在,让基类指针指向派生类对象之一,并使用该指针调用函数。因此,在运行时,会根据对象的类型调用相应的派生类函数。

标签: c++ c++11 stdthread stdbind


【解决方案1】:

最惯用和最健壮的方式可能是这样

std::thread t([=]{pointer->proc();});

没有绑定,没有多余的辅助成员函数,没有多余提及类名的奇怪语法。

【讨论】:

    【解决方案2】:

    我会使用表格 3 :-) :

    thread* th3 = pointer->start();
    th3->join();
    

    startIBase 中为:

    thread* start()
    {
        thread* t = new thread(createBind());
    
        return t;
    }
    

    在我看来,这会隐藏更多的实现细节,并为调用者提供他期望的 API(启动一个线程)。

    【讨论】:

    • 你到底为什么要在堆上分配std::thread
    • 那么谁来释放线程对象呢?我个人认为这可能会使问题更加复杂。 ?
    • 我没有看那个方面(因为不是 Q 的一部分)——还有你的线程什么时候被破坏的?可以使用 auto_ptr 或 unique_ptr 或其他实例管理结构来解决我的取消分配问题。
    猜你喜欢
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多