创建新线程时复制构造函数调用

时间:2014-01-02 15:49:08

标签: c++ multithreading visual-studio-2013 copy-constructor stdthread

我正在阅读“C ++ Concurrency in Action”一书,以了解有关线程和C ++内存模块的更多信息。我很好奇在以下代码中调用复制构造函数的次数:

struct func
{
    func() = default;
    func(const func& _f) {}

    void operator()() {}
};

int main()
{
    func f;
    std::thread t{ f };
    t.join();

    return 0;
}

当我在Visual Studio 2013调试器中浏览此代码时,我看到复制构造函数分别被调用了四次。它从主线程调用三次,然后从新线程调用一次。我期待一个,因为它为新线程制作了一个对象的副本。为什么要创建三个额外的副本?

1 个答案:

答案 0 :(得分:1)

如果在复制构造函数中设置断点,则可以在“调用堆栈”窗口中看到构造函数调用上下文。在调试模式下,我在调用构造函数时找到了下一个点:

  • 首先将函数对象复制到辅助函数bind

  • 然后将功能对象移动到内部功能对象_Bind

  • 之后,创建了一个用于启动线程_LaunchPad的类。在
    一个构造函数,它采用对_Bind实例的右值引用,所以我们有 另一个移动构造函数调用

  • 在新线程中创建_LaunchPad的副本时,会调用{{1}}的移动构造函数。

因此,在您的情况下,我们有4个复制构造函数调用。如果你添加了移动构造函数,你会看到1个复制构造函数和3个移动构造函数调用。

在发布模式下,所有空构造函数调用都被删除,汇编代码看起来非常简单