移动构造函数矫枉过正

Ili*_*oly 4 c++ move-constructor move-semantics c++11

我有一个类,它包含一个指向大块已分配内存和许多基本类型成员的指针.我正在考虑移动构造函数,并认为这是一个使用它的绝佳机会.显然,如果对于基元是一个好主意,指针应该移动但是idk.

以下是该课程的一个人为设想的例子:

class Foo {
private:
  long m_bar = 1;
  /* 20+ similar members */
};
Run Code Online (Sandbox Code Playgroud)

为了使它们可移动,必须动态分配它们.

class Foo {
public:
  Foo(Foo && rhs) : m_bar(rhs.m_bar) { rhs.m_bar = nullptr; }
  ~Foo() { delete m_bar; }
private:
  long *m_bar = new long{1};
};
Run Code Online (Sandbox Code Playgroud)

我的问题是,分配在堆上的开销是否会使移动语义引入的性能增加无效?

Sea*_*ine 6

如果有的话,我相信像这样分配每个成员的堆最终会变慢.在初始堆分配之上,仅在构造时执行,在堆上保存指向许多小的,非连续数据成员的指针不能很好地与CPU缓存策略一起使用.

有些类移动得很好,因为它们有大量堆分配的内存(例如std :: string).在您的情况下,移动每个指针将与移动较小的数据类型一样昂贵.我可以看到这个更快的唯一方法是将较小的数据成员包装在堆分配的类/结构中(可能包含一个unique_pointer).并通过单个指针的移动移动所有这些.

也就是说,这很可能是过早优化的情况.您可能希望让代码工作原理并确定为您的类实现更复杂的移动语义确实可以真正帮助您的代码的性能.

  • +1为过早优化.此外,它取决于OP如何使用此类.如果它经常被构造而不是移动,那么移动的成本可能比堆在构造上分配数据结构更值钱. (3认同)