避免 C++ 向量复制

Avoid c++ vector copy

我想避免复制非常大的向量。这是问题所在的一个非常清楚的例子:

struct MyStruct {
    std::vector<int> v;
    int x;
}

class MyClass {
    MyStruct lastStruct_;
public:
    MyStruct create_struct() {
        MyStruct s = { std::vector<int>(1000000, 1), 1234 };
        lastStruct_ = s;  // THIS IS A FULL COPY, PROBLEM
        return s; // THIS SHOULD NOT BE A COPY AS PER C++11 AND UP
    }
    MyStruct getLastStruct() {
            return lastStruct_;
    }
}

void main()
{
    MyClass c;
  for (int i = 0; i < A_LOT; i++)
  {
    writeToDisk(c.create_struct());
  }
  //MEANWHILE IN OTHER THREAD:
  // while(true)
  //   updateUI(c.getLastStruct());
}

如何避免在此处复制?我正在尝试用共享指针解决这个问题,但我对这些还是陌生的。这样的东西会起作用吗(语法可能不对)?

struct MyStruct {
    std::vector<int> v;
    int x;
}

class MyClass {
    std::shared_ptr<MyStruct> lastStruct_;
public:
    MyStruct create_struct() {
        auto s = std::maked_shared<MyStruct>({ std::vector<int>(1000000, 1), 1234 });
        lastStruct_ = s;
        return *s; 
    }
    std::shared_prt<MyStruct> getLastStruct() {
            return lastStruct_;
    }
}

void main()
{
    MyClass c;
  for (int i = 0; i < A_LOT; i++)
  {
    writeToDisk(c.create_struct());
  }
  //MEANWHILE IN OTHER THREAD:
  // while(true)
  //   updateUI(c.getLastStruct()->data());
}

这是最明显的方法:

struct MyStruct {
    std::vector<int> v;
    int x;
}

class MyClass {
    std::shared_ptr<MyStruct> lastStruct_;
public:
    std::shared_ptr<const MyStruct> create_struct() {
        auto s = std::maked_shared<MyStruct>({ std::vector<int>(1000000, 1), 1234 });
        // acquire lock
        lastStruct_ = s;
        // release lock
        return s; 
    }
    std::shared_ptr<const MyStruct> getLastStruct() {
        // acquire lock
        auto j = lastStruct_;
        // release lock
        return j;
    }
}

void main()
{
  MyClass c;
  for (int i = 0; i < A_LOT; i++)
  {
    auto j = c.create_struct();
    writeToDisk(*j);
  }
  //MEANWHILE IN OTHER THREAD:
  // while(true)
  // {
  //   auto j = c.getLastStruct();
  //   updateUI(j->data());
  // }
}

请注意,我们通过用指向新对象的共享指针替换指向旧对象的共享指针来替换对象。访问旧对象的代码会使其保持活动状态,直到它完成为止。

您需要某种锁来保护 lastStruct_ 在一个线程中被修改而在另一个线程中被访问。