C++中的前缀和后缀运算符

5
class compl{
    float re,im;

public:
    compl(float r, float i)
        {re=r; im=i;}
    compl& operator++()
        {++re; return*this;} //(1)
    compl operator++(int k){
        compl z=*this; re++; im+=k; return z;} //(2)
    friend compl& operator--(compl& z)
        {--z.re; return z;}
    friend compl operator--(compl& z,int k)
        {compl x=z; z.re--; z.im-=k; return x;}
};

(1) 为什么我们必须通过引用返回当前对象? 换句话说, 引用只是某个东西的另一个名称。

(2) 为什么我们必须将当前对象保存在z中,然后改变该对象并返回未更改的z? 这样做是因为后缀运算符的工作方式吗(它返回旧值,然后增加它)?


2
  1. 运算符链式调用
  2. 后置自增*
- crashmstr
我想问一下,为什么你把后缀运算符定义为friend函数?它们完全可以作为成员函数。 - vsoftco
这是书中的一个例子。因为它们改变参数的值,所以将它们编写为成员函数会更好吗? - Kioko Key
@KiokoKey 我看不出为什么要使用 friend。它们与您的对象紧密相关,因此它们应该是成员函数。通常,您会将某些解耦函数设置为 friend,以便可以访问您的私有/受保护成员,例如 operator<< - vsoftco
3个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
2

(1) 你不一定要这样做,但它是惯用法,因为它允许链接运算符或调用。

(2) 是的,后缀应该返回先前的值。


0

1- 运算符++重载必须返回引用,但如果您不需要变量的别名,则可以添加一个名为next或类似结构的函数。

2- 是的,因为您需要返回当前值,然后递增变量。


-2

(1) 因为我们也希望 ++ 返回一个值,就像这样

a = b++;

而且它的成本要低于返回副本。

(2) 是的,这就是后缀操作符的工作方式。这也解释了为什么通常建议使用前缀递增来编写带有迭代器的循环。

for(iterator it = ..... ; it != .... , ++it) { ...}

使用前缀自增运算符:它避免了建立临时副本。


(1)不正确,OP问的是为什么前缀operator++必须返回引用。 - vsoftco
  1. 它必须返回一些值,以便我们可以在赋值中使用它。这只留下两种可能性
  • 按值传递
  • 按引用传递
  1. 按值返回的成本更高 - 并且如果增量作为参数传递给函数(按引用),则不起作用。
- Michel Billaud
同意,但你对(1)的解释不正确。首先,你在那里有一个后缀。其次,即使++b返回一个引用(除非当然a是一个引用),a = ++b仍然会进行复制。它确实有用的情况是在像++b = something这样的赋值中。 - vsoftco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,