在不重复的情况下传递堆栈对象的所有权



第三方库具有APIHuge computeHuge()。它返回对象本身,而不是引用/指针。我无法控制对象或API。

我有两个班:

class Bar {
Huge h;
Bar(Huge &huge): h(huge);
}
class Foo {
Bar b;
Foo() {
Huge h = computeHuge();
b = Bar(h);
}

不幸的是,这种设计(暂时(导致了一个巨大对象的两个副本:一个副本存在于Foo构造函数中,另一个副本位于Bar对象内部。一旦Foo构造函数退出,就只有一个副本,但我需要将构造函数内的内存增加一倍。由于h可能是数百GB,所以这很重要。

这个问题的一个解决方案是使Foo成为h:的所有者

class Bar {
Huge &h;
Bar(Huge &huge): h(huge);
}
class Foo {
Bar b;
Huge h;
Foo() {
h = computeHuge();
b = Bar(h);
}

这确实成功地消除了h的两个副本,但在我的应用程序中这并没有什么意义:Bar是保存h的正确方法。如何:

  1. Foo构造函数中调用computeHuge()
  2. Bar保留对h的所有权
  3. 没有的所有在内存中都需要两份h

如果Huge是可移动的,则不会进行任何复制:

class Bar {
Huge h;
Bar(Huge huge): h(std::move(huge)) {}   // move huge into its final place, h
};
class Foo {
Bar b;
Foo() {
Huge h = computeHuge();
b = Bar(std::move(h));   // move h into constructor argument
// h cannot be used here anymore
}
};

出于调试目的,这是一个(微小的(Huge,不能复制,只能移动。每次复制都是编译器错误:

struct Huge {
Huge() = default;
Huge(Huge&& other) { std::cout << "move "; }
Huge(const Huge& other) = delete;
Huge& operator=(Huge&& other) { std::cout << "move= "; return *this; }
Huge& operator=(const Huge& other) = delete;
};

最新更新