【问题标题】:How does C++ know that an increment ++ is prefix or postfix when overloading the operatorC++在重载运算符时如何知道增量++是前缀还是后缀
【发布时间】:2018-01-16 03:40:38
【问题描述】:

我了解如何制作前缀和后缀增量器。在我的班级 DoStuff 中,我有:

// Prefix; returns the incremented value
friend const DoStuff& operator++(DoStuff& a);
// Postfix: returns the incremented value
friend const DoStuff operator++(DoStuff& a, int);

在课外,我有

const DoStuff& operator++(DoStuff& a){
    a.num++;
    return a;
}

const DoStuff operator++(DoStuff& a, int){
    DoStuff before(a.num);
    a.num++;
    return before;
}

分别用于前缀和后缀增量器。我不明白的是,C++ 怎么知道前者由++a 表示,而后者由a++ 表示。据我所知,前缀增量器引用了地址&,这在某种程度上意味着++ 运算符符号应该出现在它之前。 另外,我不太清楚为什么后缀需要int 变量。

【问题讨论】:

  • 它知道,因为标准是这么说的,见[over.inc]。
  • 虚拟int用于区分。它已被优化掉。
  • 根据this,您的运算符应该是成员而不是全局函数。你真的应该看看那里的问答环节,因为它几乎涵盖了与运算符重载有关的所有内容。
  • 为什么这样的问题被否决了?这似乎是一个新成员提出的一个很好的问题。不应该鼓励这样做吗?

标签: c++ operator-overloading increment prefix postfix


【解决方案1】:

当编译器读取您的源代码时,它可以判断您使用的是前缀还是后缀。非常简单:++ 出现在某个对象之前或之后。

然后编译器会生成代码来调用正确的函数。但是该函数的名称是什么?设计 C++ 的人决定将重载运算符的函数名称命名为 operator,后跟要重载的运算符(++--= 等),例如 operator*operator- 等.

但现在的问题是前缀和后缀增量运算符都命名为operator++。你如何区分它们?当您遇到++varvar++ 时,编译器会生成代码来为它们调用operator++,但您不希望这样,因为现在您无法区分后缀和前缀递增运算符之间的定义.

为了解决这个问题,相同的语言设计者添加了一个虚拟参数int。这样,编译器在遇到后缀++时可以调用operator++(0)operator++(42)(或任何你喜欢的数字,它并不重要。它是一个虚拟参数),遇到后缀时只调用operator++()一个前缀。该参数只是用于区分。

总而言之,这是一个语言设计问题。当涉及到设计决策时,自然会有其他解决方案(比如将它们命名为operator_preinc()operator_postinc()),但这正是 C++ 的设计者选择的方案。他们可能有自己的理由,也可能是任意选择的,因为也许所有其他选项的权重都差不多。

【讨论】:

    猜你喜欢
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多