0

正如https://stackoverflow.com/a/3279550/943619巧妙地描述的那样,正确的实现operator=方式通常是:

my_type& operator=(my_type other) {
    swap(*this, other);
    return *this;
}
friend void swap(my_type& lhs, my_type& rhs) { ... }  // This can vary some.

然而,Howard Hinnant 指出,有时可以通过为左值和右值参数实现单独的重载来做得更好:

my_type& operator=(const my_type& other) { ... }
my_type& operator=(my_type&& other) { ... }

显然 2-overload 解决方案可以在几种情况下节省一步,但这样小的改进不太可能出现在基准测试中。相反,我正在寻找编写 2 个重载可以使性能提高一倍的情况。

4

1 回答 1

1

“复制和交换”习语的主要问题是效率较低。

即使我们有一个好的swap实现,我们仍然一次有 3 个类的实例,而左值和右值运算符的另一个解决方案只有 2 个实例。

这意味着我们需要多出 50% 的内存用于复制和交换,而且还可能需要大量的时间成本——因为您必须获取原本不需要的资源。

想想这种情况:如果你这样做并且两者都具有相同的大小,std::vector则使用左值引用vec1=vec2;- 你根本不需要做任何事情。在复制和交换中,您必须创建第三个向量 - 所以您有一个额外的向量,这可能需要很长时间(如果向量很小,则很重要)或大量内存(如果向量很大)newdeletenewdelete

复制和交换的主要优点是异常安全。复制和交换为您提供强大的异常安全性,但以性能为代价。

如果您需要异常安全 - 使用它。如果您需要性能(内存、时间、您的课程需要的任何其他资源),请不要使用它。

于 2013-10-22T18:30:05.193 回答