3

1)有什么区别:

complex& operator = (const complex& c);

complex operator = (complex c);

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

complex::complex (const complex& c){

    //code
    }

3) const 的作用是什么?

4

5 回答 5

5

这些是非常不同的

你想要链式作业吗?返回*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并返回一个临时副本,然后分配给该临时对象(对orc没有影响)。ab

如您所见,结果是不同的。忽略发生了什么以及哪个更好。您应该选择一种对程序员来说很流行和期望的方式。我相信 C++ 程序员通过观看(a = b) = c期待第一个结果。

因此,您应该使用第一个。

 

关于关键字const

当您通过对函数的引用传递对象时,该函数可以修改它。您可以放置​​一个const来保护它免受不必要的更改。

于 2013-09-26T21:16:53.967 回答
1

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

第二个可以工作,但它会产生不必要的副本,并且您不能在分配给的对象上调用函数,如下所示:(a = b).dosth()因为它返回一个不同的对象。我的意思是它会编译,但它会调用dosth一个临时对象。

2)它们从来都不一样,但是如果您没有可访问的副本ctor(或有时移动ctor),则第二个将不起作用。

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

于 2013-09-26T20:46:39.647 回答
0

它们不一样,第一个传递引用,因此对象保留在内存中,第二个将需要copy-ctor,因为complex对象将被复制进和复制出函数。第一个是规范的,你想要什么,第二个没有被使用,因为它是不必要的浪费。

于 2013-09-26T20:46:57.383 回答
0

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

“引用”——通过添加&符号选择——意味着这个函数实际上使用了用户给出的相同对象,来自相同的内存。由于它使用的是同一个对象,因此您承诺不会更改该对象很重要。

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

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

于 2013-09-26T20:48:20.270 回答
0

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

complex operator=(complex c);

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

通过引用传递,如:

complex& operator=(complex& c);

意味着传递给操作员的对象不会被复制。

第二个区别是他们返回的内容。运算符的正确形式是返回对自身的引用。您提供的第一个表单实际上返回了对象的副本,这同样可能是低效的。

最后,运算符的正确形式再次将输入对象作为const参考。这更像是一个风格问题,而不是与性能有关的任何事情——但人们不会合理地期望赋值运算符修改输入对象,并将其指定为const防止这种情况发生。

所以总结一下,

complex& operator=(const complex& c);

是正确的形式。

于 2013-09-26T20:49:43.503 回答