最佳答案
请将本主题视为下列主题的续集:
上一期
未定义行为和序列点
让我们回顾一下这个 有意思和 很复杂表达式(斜体的短语取自上面的主题 * smile *) :
i += ++i;
我们说这会引起未定义的行为。我假设当我们这样说时,我们隐式地假设 i
的 类型是内置类型之一。
如果 i
的 类型是用户定义的类型,该怎么办?假设它的类型是 Index
,这是在本文后面定义的(见下文)。它还会调用未定义的行为吗?
如果是,为什么?它难道不等同于编写 i.operator+=(i.operator++());
或者甚至语法上更简单的 i.add(i.inc());
吗?或者,它们也会调用未定义的行为吗?
如果没有,为什么不呢?毕竟,对象 i
在连续的序列点之间得到修改的 两次。请回忆一下经验法则: 表达式只能在连续的“序列点”之间修改一次对象的值。如果 i += ++i
是一个表达式,那么它必须调用未定义的行为。如果是这样,那么它的等价物 i.operator+=(i.operator++());
和 i.add(i.inc());
也必须调用未定义的行为,这似乎是不真实的!(据我所知)
或者,i += ++i
本来就不是 表情?如果是这样,那么它是什么? 表情的定义是什么?
如果它是一个表达式,同时它的行为是 还有定义良好的,那么它意味着与一个表达式相关联的序列点的数目在某种程度上取决于参与表达式的操作数的 类型。我说的对吗?
顺便问一下,这个表达怎么样?
//Consider two cases:
//1. If a is an array of a built-in type
//2. If a is user-defined type which overloads the subscript operator!
a[++i] = i; //Taken from the previous topic. But here type of `i` is Index.
您必须在响应中也考虑到这一点(如果您确切地知道它的行为)。 : -)
就是
++++++i;
在 C + + 03中定义良好? 毕竟这是这个,
((i.operator++()).operator++()).operator++();
class Index
{
int state;
public:
Index(int s) : state(s) {}
Index& operator++()
{
state++;
return *this;
}
Index& operator+=(const Index & index)
{
state+= index.state;
return *this;
}
operator int()
{
return state;
}
Index & add(const Index & index)
{
state += index.state;
return *this;
}
Index & inc()
{
state++;
return *this;
}
};