C++ 如何以两种不同的方式为后缀 a++ 和前缀 ++a 重载运算符++?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3846296/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:53:03  来源:igfitidea点击:

How to overload the operator++ in two different ways for postfix a++ and prefix ++a?

c++operator-overloading

提问by rookie

How to overload the operator++ in two different ways for postfix a++and prefix ++a?

如何以两种不同的方式为 postfixa++和 prefix重载 operator++ ++a

回答by Martin York

Should look like this:

应该是这样的:

class Number 
{
    public:
        Number& operator++ ()     // prefix ++
        {
           // Do work on this.   (increment your object here)
           return *this;
        }

        // You want to make the ++ operator work like the standard operators
        // The simple way to do this is to implement postfix in terms of prefix.
        //
        Number  operator++ (int)  // postfix ++
        {
           Number result(*this);   // make a copy for result
           ++(*this);              // Now use the prefix version to do the work
           return result;          // return the copy (the old) value.
        }
}; 

回答by stakx - no longer contributing

The difference lies in what signature you choose for your overload(s) of operator ++.

不同之处在于您为operator ++.

Cited from the relevant article on this subject in the C++ FAQ(go there for more details):

C++ FAQ 中关于这个主题的相关文章中引用(去那里了解更多细节):

class Number {
  public:
    Number& operator++ ();     // prefix ++: no parameter, returns a reference
    Number  operator++ (int);  // postfix ++: dummy parameter, returns a value
};
class Number {
  public:
    Number& operator++ ();     // prefix ++: no parameter, returns a reference
    Number  operator++ (int);  // postfix ++: dummy parameter, returns a value
};

P.S.:When I found out about this, all I saw initially was the dummy parameter, but the different return types are actually more interesting; they might explain why ++xis considered more efficient than x++in general.

PS:当我发现这个时,我最初看到的只是虚拟参数,但不同的返回类型实际上更有趣;他们可能会解释为什么++x被认为比x++一般情况下更有效率。

回答by paercebal

You have two ways to overload the two (prefix/postfix) ++ operators for a type T:

您有两种方法可以为类型 T 重载两个(前缀/后缀)++ 运算符:

Object method:

对象方法:

This is the easiest way, using "common" OOP idiom.

这是最简单的方法,使用“通用”OOP 习语。

class T
{
    public :
        T & operator++() // ++A
        {
            // Do increment of "this" value
            return *this ;
        }

        T operator++(int) // A++
        {
           T temp = *this ;
           // Do increment of "this" value
           return temp ;
        }
} ;

Object non-member function:

对象非成员函数:

This is another way to do this: As long as the functions are in the same namespace as the object they are referring too, they will be considered when the compiler will search for a fonction to handle ++t ;or t++ ;code:

这是执行此操作的另一种方法:只要函数与它们所引用的对象位于相同的命名空间中,编译器将在搜索要处理的函数++t ;t++ ;代码时考虑它们:

class T
{
    // etc.
} ;


T & operator++(T & p_oRight) // ++A
{
   // Do increment of p_oRight value
   return p_oRight ;
}

T operator++(T & p_oRight, int) // A++
{
   T oCopy ;
   // Copy p_oRight into oCopy
   // Do increment of p_oRight value
   return oCopy ;
}

It is important to remember that, from a C++ viewpoint (including a C++ compiler viewpoint), those non-member functions are still part of T's interface (as long as they are in the same namespace).

重要的是要记住,从 C++ 的观点(包括 C++ 编译器的观点)来看,那些非成员函数仍然是 T 接口的一部分(只要它们在同一个命名空间中)。

There are two potential advantages of the non-member function notation:

非成员函数符号有两个潜在的优点:

  • If you manage to code them without making them friend of T, then you increased the encapsulation of T
  • you can apply this even to classes or structures whose code you don't own. This is a non-intrusive way to enhance the interface of an object without modifying its declaration.
  • 如果你设法编码它们而不让它们成为 T 的朋友,那么你增加了 T 的封装
  • 您甚至可以将其应用于您不拥有其代码的类或结构。这是一种在不修改对象声明的情况下增强对象接口的非侵入式方法。

回答by Kate Gregory

Declare like so:

像这样声明:

class A
{
public:
    A& operator++();    //Prefix (++a)
    A operator++(int); //Postfix (a++)

};

Implement properly - do not mess with what everyone knows they do (increment then use, use then increment).

正确实施 - 不要混淆每个人都知道他们所做的事情(先增加然后使用,使用然后增加)。

回答by X. Mora

I know it's late, but I had the same problem and found a simpler solution. Don't get me wrong, this is the samesolution as the top one (posted by Martin York). It is just a bitsimpler. Just a bit. Here it is:

我知道已经晚了,但我遇到了同样的问题并找到了一个更简单的解决方案。不要误会我的意思,这与上面的解决方案相同(由 Martin York 发布)。它只是简单一点。一点点。这里是:

class Number
{
        public:

              /*prefix*/  
        Number& operator++ ()
        {
            /*Do stuff */
            return *this;
        }

            /*postfix*/
        Number& operator++ (int) 
        {
            ++(*this); //using the prefix operator from before
            return *this;
        }
};

The above solution is a bit simpler because it doesn't use a temporary object in the postfix method.

上面的解决方案稍微简单一些,因为它没有在 postfix 方法中使用临时对象。