传递堆栈对象的所有权而不重复

克罗基亚

第三方库具有API Huge 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. 调用computeHuge()Foo构造
  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;
};

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章