我正在阅读《 C++并发操作》一书,以了解有关线程和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调试器中遍历此代码时,我看到复制构造函数被调用了四个不同的时间。从主线程中调用它三次,然后从新线程中调用一次。我期待一个,因为它为新线程复制了该对象。为什么要创建三个额外的拷贝?

最佳答案

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

  • 首先将功能对象复制到辅助函数bind
  • 然后将功能对象移动到内部功能对象_Bind
  • 之后,将创建一个用于启动线程_LaunchPad的类。在
    一个构造函数,它需要引用_Bind实例的右值,所以我们有
    另一个 Action 构造函数调用
  • 在新线程中创建_LaunchPad
  • move构造函数时,将调用它的拷贝。

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

    在 Release模式下,所有空的构造函数调用都将被消除,并且汇编代码看起来非常简单

    关于c++ - 创建新线程时复制构造函数调用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20886526/

    10-09 07:49
    查看更多