2013-10-29 96 views
-1

我读了C++ primer第5版。当我们在使用复制和交换的赋值操作符中使用非参考参数时,我发现它是可以的,但在其他赋值操作符中,我们总是使用参考参数并在销毁左操作数之前复制右手操作数,以确保如果一个对象被分配给自己,赋值操作符就可以正常工作为什么不在将在函数体中稍后复制的赋值运算符中使用非引用参数,以便我们不需要复制函数体中的右侧操作数?为什么要在C++中通过引用传递赋值运算符的参数?

+1

请显示您正在谈论的代码。 – greatwolf

回答

3

复制赋值操作符通常应该按值(不是引用)采用它们的参数,以便使用by-value参数作为副本进行复制和交换。

如果你没有做(只是)复制和交换,那么也许你的副本赋值运算符应该通过引用采用它的参数。至于你为什么不做复制和交换:可能是因为该类型的某些特定的优化。考虑一个简单可复制类型的std::array(为避免谈论异常安全性的麻烦,我们可以省略一点)。最有效的可能的任务是直接复制字节:不需要对象的临时副本,并且您肯定不需要交换。因此,在实践中,您需要通过参考采用参数,编写std::copy,并期望编译器以最佳方式执行此操作。

复制赋值运算符中的特殊外壳自赋值有时会在教科书中看到,即使使用了copy-and-swap,但在C++ 03中通常是一个坏主意。虽然它优化了自我分配的情况,但通过引用参数可以优化临时分配的情况。在C++ 11中,它不太明显不好,因为临时分配的情况可以由移动赋值运算符而不是复制赋值运算符来处理。但它可能仍然没有必要。在实际代码中,自分配很少见,因此甚至可以发现,在极少数情况下,常见情况下的指针比较运算结果高于。

我还没有阅读第五版的“C++ Primer”,并且你选择不显示你询问的代码,所以我不能评论它给出赋值操作符的具体情况(复制分配或以其他方式),通过引用参数。

对不起,但总的来说,我认为这是统计上更可能你感到困惑比书;-)你说:

...在使用复制和交换赋值运算符,但在其他赋值运算符

好了,“其他赋值运算符”是赋值运算符是使用复制和交换?

我们一直使用的参考参数和销毁 左侧操作数

之前复制右手操作如果复制右侧操作数,那么你做复制和交换。或者至少你非常接近它,因为做了一个副本,除了交换以外,没有什么意义可以使副本进入左侧。无论哪种方式,如果一个函数的第一件事是复制一个引用参数,那么它应该已经通过值获取参数。

以确保赋值运算符正常工作,如果一个对象被分配到自身

如果您确保自分配技术工作正确方法是始终复制右手操作数,那么你应该按值来取参数。没有其他需要。但是,还有其他技术可以确保自我分配工作。有可能其中之一发生在你没有显示的代码中。

+0

非常感谢你的回答,我之所以没有显示代码是因为我有点懒惰:(我认为我可以清楚地表达出来,但是...我很抱歉,无论如何,我已经得到了我的回答,谢谢 – Sherwin

0

主要原因是效率。对于一个小类/结构体来说,它可能并不重要,但如果它是一个大型复杂类,那是另一回事。如果您按值传递,则将调用可能较大且复杂的复制操作。这可能需要大量的内存分配。

真正的答案是有时候没关系。通常它确实是很重要,所以最好的方法就是始终使用参考。

+0

但在我的情况下,它复制在函数体后面,这两者之间有什么不同吗? – Sherwin

+0

在某些时候,你总是要做某种形式的复制或分配(无论是愚蠢的整个事物的memcopy,成员或者成员,或者任何有意义的东西,但是如果你将值传递给你的操作符,那么在你进入操作符的主体之前,你还使用拷贝构造函数创建了一个额外的对象。 – mjs

+0

@SteveJessop您可以单向读取问题,也可以读取另一个问题。也许如果OP发布代码....... – mjs

相关问题