Summary of overload and performance analysis of C++ auto increment and auto subtract operators

  • 2020-06-19 11:26:33
  • OfStack

01 ++, -- the format of the operator overload function

Autoincrement operators and autodecrement operators are prepositional and postpositional, as follows:


a++ //  Post - increment operator 
++a //  The prefix autoincrement operator 

b-- //  Postsubtractive operator 
--b //  Presubtractive operator 

In order to distinguish whether the overloaded pre-operator or post-operator, C++ specifies:

The prefix operator is overloaded as a 1-element operator, and the format of the overload as a member function is as follows:


T & operator++(); //  An overloaded function premounted by an autoincrement operator with an empty argument 
T & operator--(); //  An overloaded function with a pre-subtractive operator with an empty argument 

The post-operator is overloaded as a 2-element operator, one more useless parameter is written, and the number of overloaded as a member function is as follows:


T operator++(int); //  The overloaded function of the post - additive operator, multi 1 It's a useless parameter 
T operator--(int); //  The overloaded function of the postsubtractive operator, multiple 1 It's a useless parameter 

02 discusses the return values of pre - and post-operators

The pre - and post-operator overload functions are as follows:

前置运算符重载的成员函数 后置运算符重载的成员函数
T & operator++(); T operator++(int);
T & operator--(); T operator--(int);

Notice the difference? So here's the question:

Why does the leading operator return a reference & ? Why does the post-operator return normal objects (temporary objects)?

Mainly because in order to maintain the original C++ pre - and post-operator characteristics:

The property of the preposition operator


int a = 0

// (++a) = 5;  It can be taken apart :
// a = a + 1; 
// a = 5;
(++a) = 5; //  Pre - ++

The value of a is 1 after adding +1, and then a=5, so the value of a is 5.

This indicates that (++a) returns the self-increasing a variable, and the value of a variable will be modified during the subsequent operation of the a variable. So the return value of an overloaded function with a preposition operator must be a reference & .

Properties of post-operators

The postposition operator cannot be left value, that is, (a++) = 5; The return value of the overloaded function of the post-operator is a normal object.

03 ++, - operator overloading function preparation


int main()
{
  CDemo d(10);
  cout << d++ << ","; //  Is equivalent to  d.operator++(0);
  cout << d << ","; 
  
  cout << ++d << ","; //  Is equivalent to  d.operator++();
  cout << d << ",";
  
  cout << d-- << ","; //  Is equivalent to  d.operator--(0);
  cout << d << ",";
  
  cout << --d << ","; //  Is equivalent to  d.operator--();
  cout << d << endl;
  
  return 0;  
}

Output results:

[

10,11,12,12
12,11,10,10

]

Suppose you want to implement the output of the above main function, how would you write it?

First, we define the CDemo class, and also define the overload functions of the increment and decrement operators.


class CDemo
{
public:
  CDemo(int i = 0):m_num(i) {} //  The constructor 
  
  CDemo & operator++();  //  Preadditive operator overload 
  CDemo operator++(int); //  Post - additive operator overload 
  
  CDemo & operator--();  //  Presubtractive operator overload 
  CDemo operator--(int);  //  Post - subtractive operator overload 

private:
  int m_num; //  Member variables 
};

Then continue to implement the preadditive and subtractive operators overload functions:


//  Pre - ++
CDemo & CDemo::operator++()
{
  ++m_num;
  return *this;
}

//  Pre - --
CDemo & CDemo::operator--()
{
  --m_num;
  return *this;
}

The overloading of postposition autoincrement and autodecrement operators is a little different. For example, the postposition ++ takes part in the operation first and then autoincrement. Therefore, the return value is the object before the autoincrement.


//  The rear ++
CDemo CDemo::operator++(int)
{
  CDemo tmp(*this); //  Record the modified object 
  m_num--;
  return tmp;    //  Returns the modified object 
}

//  The rear --
CDemo CDemo::operator--(int)
{ 
  CDemo tmp(*this); //  Record the modified object 
  m_num++;
  return tmp;    //  Returns the modified object 
}

Performance comparison of the 04 pre - and post-operators

From the above example, we see the steps to perform the overloaded function of the post-operator:

First, a temporary object is generated to hold the object before it is added or subtracted. Then the member variable increases or decreases; Finally, return the modified object.

The execution steps of the overloaded function of the preposition operator:

Member variables are self-increasing or self-decreasing; Returns an object reference;

It can be seen that the overload function of the pre-operator is higher in performance and less in overhead than that of the post-operator.

Of course, for common variable types, such as int, double, long, etc., the performance gap between the front and rear is small. The important thing is that when we use autoincrement or decrement for objects and iterators, it is best to use the prefix operator, which reduces overhead.


Related articles: