后增量运算符如何与用户定义的类型一起使用?

时间:2018-12-29 18:30:55

标签: c++

对于此后递增运算符如何处理用户定义的类型,我遇到了一个难题:正如我猜想,后递增运算符operator++(T _unused)首先保存原始值(到表达式中),然后递增变量。例如:

int x{5};
int y{x++};

所以x = 6y = 5没关系。

但这是用户定义的示例:

struct s{
    int x;
    s(int m_) : x(m_){}
    s operator++(int){ x++; return *this;}
};


int main(){

    s a(0);
    a.x = 7;
    cout << "a::x: " << a.x << endl;

    s b(a++);

    cout << "a::x: " << a.x << endl; // 8
    cout << "b::x: " << b.x << endl; // 8 ?!

    int t = 9;
    s c(t++);

    cout << "c::x: " << c.x << endl; // 9
    cout << "t: " << t << endl; // 10 ok

    cout << endl;
    return 0;
}

正如您在上面看到的:s b(a++)将使a.xb.x 8的值吗?我不明白为什么?

谢谢你们的帮助,时间和精力。

5 个答案:

答案 0 :(得分:3)

将运算符更改为此:

s operator++(int){ 
   s t{x++};
   return t;
}

问题是您正在定义操作符,该操作符会在返回之前修改this,并且返回的是修改后的this的副本,您需要创建一个新的{{1 }},其值为s,然后进行修改并返回。

答案 1 :(得分:3)

  

后增量运算符如何与用户定义的类型一起使用?

编写方式,因为它通常是常规方法。

避免意外是一种很好的做法,因此内置类型的模仿行为是好的。

要模仿内置类型为int,可以将实现固定为:

struct s
{
    int x;
    explicit s(int m_) : x(m_){}
    s& operator++(){ ++x; return *this;} // pre-increment
    s operator++(int){ auto res = *this; ++*this; return res;} // post-increment
};

答案 2 :(得分:2)

仅在函数签名中添加int不会得到后递增:您必须实际实现它!

您的代码:

s operator++(int){ x++; return *this;}

对我来说,这就像是预先增加的。尽管在编写someSObject++时会调用它,但是它所做的只是增加对象自己的x的值,然后返回对象的副本。

相反,我认为您的意思是:

s operator++(int)
{
    S result{*this};
    ++(*this);
    return result;
}

或者,为简洁起见,针对该特定类别进行量身定制:

s operator++(int)
{
    return s{x++};
}

答案 3 :(得分:2)

您通常在一个类中为增量运算符提供两个重载:

class C {
public:
    C& operator++();   // pre-increment
    C operator++(int); // post-increment
    int i;
};

问题是,命名这些“前递增”和“后递增”描述的是它们的命名方式,而不是它们的作用。

C c;
++c; // calls operator++()
c++; // calls operator++(int)

要实现递增前后的通常语义,您必须编写能执行适当操作的代码。

预递增意味着递增值,并返回新值:

C& C::operator++() {
    ++i;
    return *this;
}

后递增意味着递增值并返回值:

C C::operator++(int) {
    C res(*this);
    ++*this;
    return res;
}

答案 4 :(得分:0)

您对s operator++(int){ x++; return *this;}有什么期望?

您可以看到x在复制构造函数构造临时对象之前已递增。请记住,按值返回会调用复制构造函数。您应该在增加变量之前构造临时对象。

根据您的情况,您可以将其更改为:

s operator++(int){ 
    return s(x++);
}

如您所见,临时对象是用x的值构造的,然后x递增。