对于此后递增运算符如何处理用户定义的类型,我遇到了一个难题:正如我猜想,后递增运算符operator++(T _unused)
首先保存原始值(到表达式中),然后递增变量。例如:
int x{5};
int y{x++};
所以x = 6
和y = 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.x
和b.x
8
的值吗?我不明白为什么?
谢谢你们的帮助,时间和精力。
答案 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递增。