重载运算符=按值或引用返回?

时间:2013-09-26 20:40:57

标签: c++ copy const overloading operator-keyword

1)有什么区别:

complex& operator = (const complex& c);

complex operator = (complex c);

2)如果我定义(在第二种情况下)复制构造函数,它们是否相同?

complex::complex (const complex& c){

    //code
    }

3)const的功能是什么?

5 个答案:

答案 0 :(得分:1)

1)第一个是惯用的C ++版本。它表示它需要引用参数(不是复制)并且会返回对复杂(不是副本)的引用,这通常是分配给的对象(即*this)。

第二个可以工作,但它会使不必要的副本和你不能调用被赋值的对象上的函数,如:(a = b).dosth()因为它返回一个不同的对象。我的意思是它会编译但它会在临时对象上调用dosth

2)它们不一样,但是如果你没有可访问的拷贝ctor(或者有时候移动ctor),第二个就不会工作。

3)const是一个你不会修改参数的承诺。所以在a = b你不想修改bconst强制执行。你不需要它在第二个版本(按值传递),因为你无论如何都无法修改它,因为它只是一个副本。

答案 1 :(得分:1)

那些非常不同

你想要链式作业吗?返回*this

a = b = c; // Chained assignment

C ++中的默认赋值支持链接,因此保留此规则是个好主意。

要支持这种类型的分配,每个操作都必须返回对*this的引用或返回副本:

complex& operator = (const complex& c)
{
  // do assignment

   return *this;
}

complex operator = (const complex& c)
{
  // do assignment

   return *this;
}

但这项简单的工作应该轻松有效。假设没有可用的RVO或移动,则首选返回引用而不是副本。

我更喜欢返回引用的另一个原因是在脑海中摆脱一个令人困惑的事情。请参阅以下两种情况:

// Returning a reference
a = 1;
b = 2;
c = 3;
(a = b) = c;

分配后,a=3 b=2 c=3。因为,首先b分配给a并返回对a的引用,然后c分配给该引用并再次a更改。

// Returning a copy
a = 1;
b = 2;
c = 3;
(a = b) = c;

分配后,a=2 b=2 c=3。因为,首先b分配给a并返回临时副本,然后c会分配给该临时对象(对ab无效)。< / p>

如您所见,结果不同。忽略发生的事情以及哪一个更好。您应该选择一种受程序员欢迎和期望的方式。我相信C ++程序员通过观察(a = b) = c期望第一个结果。

因此你应该使用第一个。

关于关键字const

通过引用函数传递对象时,该函数可以对其进行修改。您可以设置const以防止意外更改。

答案 2 :(得分:0)

它们不一样,第一个传递引用,因此对象保留在内存中,第二个将需要复制文件,因为complex对象将被复制到并且没有这个功能。第一个是规范的,你想要的是什么,第二个是没有使用的,因为它不必要地浪费。

答案 3 :(得分:0)

const是一种说法“我保证不会改变c!所以不要担心!”。这允许用户通过引用提供实际的类(在您的情况下为complex),而不用担心它会意外地改变。

“reference” - 通过添加&符号来选择 - 意味着此函数实际上使用了来自同一内存的用户提供的相同对象。由于它使用相同的对象,因此您承诺不更改该对象非常重要。

如果没有& - 您的第二个示例 - 您没有传递相同的对象,则传递该对象的副本。所以const是不必要的(虽然仍然合法)因为用户不在乎你是否更改了副本。

区别?时间(和大班的记忆)。如果将引用传递给对象 - 则不需要复制该对象。这节省了时间(复制对象所需的时间)和内存(对象需要的内存)。

答案 4 :(得分:0)

第二种形式通过复制而不是通过引用来获取和返回值,这通常是低效的。

complex operator=(complex c);

参数c作为原件的副本传入。对于像int这样的简单数据类型,这无关紧要,但如果complex很复杂,这可能会导致不必要的分配/解除分配并阻碍性能。

通过引用传递,如:

complex& operator=(complex& c);

表示不会复制传递给运算符的对象。

第二个区别是他们的回报。运算符的正确形式是返回对自身的引用。您提供的第一个表单实际上会返回该对象的副本,这也可能效率低下。

最后,操作符的正确形式再次将输入对象作为const引用。这是一个风格问题而不是与性能有关的问题 - 但是人们不会合理地期望赋值运算符修改输入对象,并将其指定为const可以防止这种情况。

总而言之,

complex& operator=(const complex& c);

是正确的表格。