c++ - 当添加一个移动构造函数和一个移动赋值操作符时,C++ 会真正开始改变?

  显示原文与译文双语对照的内容
52 4

考虑到今天的返回值优化( RVO和 NRVO )的高质量,我想知道什么类复杂性开始添加移动构造函数和移动运算符。

例如,对于这个 really_trivial 类,我只假设移动语义不能提供任何比RVO和NRVO在它的周围复制的情况。

class really_trivial
{
 int first_;
 int second_;
public:
 really_trivial();
. . .
};

在这个 semi_complex 类中,我将添加一个移动构造函数,并毫不犹豫地移动赋值操作符:

class semi_complex
{
 std::vector<std::string> strings_;
public:
 semi_complex(semi_complex&& other);
 semi_complex& operator=(semi_complex&& other);
. . .
};

所以,在什么类型的成员变量,它开始意义是添加移动构造函数和移动分配运算符。

时间:原作者:0个回答

51 3

对于纯语义的原因,它已经经有意义了,即使你把优化方面完全。想象一下类不存在/无法实现复制的情况。例如无法复制 boost::scoped_ptr,但可以将它的移动 !

原作者:
119 3

除了已经给出的优秀答案之外,我还想添加一些前进的详细信息:

最近C++0x草案中有新的规则用于自动生成移动构造函数和移动赋值操作符。虽然这个想法并不全新,但是最新规则只在 2010年10月 中进行,并且尚不能在编译器中广泛使用。

如果你的类没有声明复制构造函数,复制赋值运算符,移动构造函数和析构函数。这些默认实现将简单地将所有的。

你还可以显式地默认移动成员:

semi_complex(semi_complex&&) = default;
semi_complex& operator=(semi_complex&&) = default;

注意,如果这样做,你将隐式禁止复制语义,除非显式提供或者默认复制构造函数和复制操作符。

在相关的后期中断更改中:如果类具有显式析构函数和隐式复制成员,则这些成员的隐式生成现在已经过时。

总之,当你声明了一个析构函数时,你可以能需要考虑显式声明复制和移动成员。

原作者:
81 2

作为一个经验规则,我会说,每当有成员变量包含( 有条件的) 动态分配内存时,就会。如果你可以以使用现有内存并给出它所需要的最小分配,那么它通常会更便宜。成员变量的量不重要,因为对于不涉及动态内存的类型,不可以能不同于复制或者移动( 移动构造器也必须将它们从一个内存位置复制到另一个内存位置) 。

因此移动semantices是有意义

  • 动态内存分配涉及
  • 移动对一个或者多个成员变量( 也就是说那些涉及到动态分配的地方) 有意义。
原作者:
...