C++前置自增运算符和后置自增运算符的重载

本文是关于重载单目运算符的实战讲解,用两个例子进行说明。理论不多,重在理解前置++和后置++的区别。在看本文之前,您需要了解运算符的重载的基本概念。如果不懂,也没关系,请进下面的传送门。

浅显易懂的C++运算符重载

理论:

  1. 前置单目运算符,重载函数没有形参。
  2. 后置单目运算符,重载函数需要一个int形参。只起到区别前置运算符的的作用。

人狠话不多,来,小二,上茶~~~

例如下面的例子:
  我们创建一个时间的类,使其能够实现时间的自增操作,包括前置自增和后置自增。

在类中我们声明了两个个++运算符的重载类型的函数:

  • Clock& operator++();,它是没有形参的,并且它的返回值类型是Clock类对象的引用,是一个左值。
  1. 在函数的实现中。我们先让当前对象的second值加一,然后对hour和minute值进行进位操作。
  2. 最后,我们返回指向当前对象的引用。可以看到它的值就是进行加一之后的值。
Clock& Clock::operator++()//返回的是加一操作之后的值的引用,是一个左值。
{
     
        this->second++;
        if (second >= 60)
        {
     
               this->second = this->second - 60;
               this->minute++;
               if (minute >= 60)
               {
     
                       this->minute = this->minute - 60;
                       this->hour = (this->hour + 1) % 24;
               }
        }
        return *this;//返回加一之后的值。
}
  • Clock operator++(int);,它有一个int型的形参,该形参没有什么之实际作用,只是用来区别前置自增运算符的重载函数,并且它的返回值是一个Clock类对象。
  1. 在函数实现中,我们先将当前对象拷贝一份,然后再对当前对象进行加一操作。
  2. 我们这里调用的是上面的前置加一操作,而没有将上面的代码再拷贝一份,那样做是愚蠢的。
  3. 我们这里使用的是24小时制来表示时间,如果我们想用12小时制来表示,我们这种写法,只需在一个函数中修改即可。而不用在两处都修改。保证了代码的可维护性。
Clock Clock::operator++(int)//返回加一操作之前的值的副本,是一个右值
{
     
        Clock old = *this;
        ++(*this);//调用前置“++”运算符
        return old;//返回++之前的值。
}
/*

操作数是自定义类
//*/
#include
using namespace std;
class Clock
{
     
public:
        Clock(int h=0,int m=0,int s=0);
        void showTime() const;
        Clock& operator++();//前置++
        Clock operator++(int);//后置++,只是和前置区分开,没有实际作用
        ~Clock();
private:
        int hour, minute, second;
};
Clock::Clock(int h,int m,int s)
{
     
        if (0 < h&&h < 24 && 0 < m&&m < 60 && 0 < s&&s < 60)
        {
     
               this->hour = h;
               this->minute = m;
               this->second = s;
        }
        else
        {
     
               cout << "Time Erro" << endl;
        }
}
Clock::~Clock()
{
     
        /*cout << "析构函数" << endl;*/
}
void Clock::showTime()const
{
     
        cout << this->hour << ":" << this->minute << ":" << this->second << endl;
}
//前置++
//先加一,后使用,使用的是加一之后的值。
Clock& Clock::operator++()//返回的是加一操作之后的值的引用,是一个左值。
{
     
        this->second++;
        if (second >= 60)
        {
     
               this->second = this->second - 60;
               this->minute++;
               if (minute >= 60)
               {
     
                       this->minute = this->minute - 60;
                       this->hour = (this->hour + 1) % 24;
               }
        }
        return *this;//返回加一之后的值。
}
//后置++
//看起来是:先使用后加一,但实际上,它已经加一了,只不过我们使用的是它加一之前的值。
Clock Clock::operator++(int)//返回加一操作之前的值的副本,是一个右值
{
     
        Clock old = *this;
        ++(*this);//调用前置“++”运算符
        return old;//返回++之前的值。
}
int main()
{
     
        Clock c1(23, 59, 59);
        cout << "当前时间:";
        c1.showTime();
        cout << "后置++:";
        (c1++).showTime();
        cout << "前置++:";
        (++c1).showTime();
        return 0;
}

我们把当前时间设置为:23:59:59
进行加一操作之后的值如下:

输出:
当前时间:23:59:59
后置++:23:59:59
前置++:0:0:1

在我们刚接触编程时,我们可能会记得:

  1. i++:是先使用当前的值,再进行加一操作。
  2. ++i:是先进行加一操作,再使用加一后的值。
    通过上面我们自己实现前置自增和后置自增,我们可以看到,都是先对当前对象进行加一操作,然后再使用,只不过,在后置自增时,我们使用的是自增之前的旧值,而当前对象实际上也已经进行了加一操作。
  3. 在上面的输出中,我们可以看到,使用后置++时,输出的值仍然是23:59:59,好像并没有进行加一操作。然而并不是的,实际上它是进行了加一操作的。
  4. 使用前置++时,我们看到当前时间是:0:0:1,相对我们设置的时间:23:59:59,加了两秒,这就证明了我们的后置++确实是进行了操作的。

再看一个例子:
  定义Point类,有坐标x,y两个成员变量;对Point类重载“++”(自增)、“–”(自减)运算符,实现对坐标值的改变。

自减和自增的写法一样。就不作过多的赘述了。

#include
using namespace std;
class Point
{
     
public:
	Point();
	Point(double x, double y);
	~Point();
	Point& operator++();//前置
	Point operator++(int);
	Point& operator--();//前置
	Point operator--(int);
	Point operator+(const Point &p)const;
	void display() const;
private:
	double x;
	double y;
};
Point::Point()
{
     
	this->x = 0;
	this->y = 0;
}
Point::Point(double x, double y)
{
     
	this->x = x;
	this->y = y;
}
Point::~Point()
{
     
	//cout << "析构函数" << endl;
}
Point& Point::operator++()
{
     
	this->x++;
	this->y++;
	return *this;
}
Point Point::operator++(int)
{
     
	Point oldpoint = *this;
	++(*this);
	return oldpoint;
}
Point& Point::operator--()
{
     
	this->x--;
	this->y--;
	return *this;
}
Point Point::operator--(int)
{
     
	Point oldpoint = *this;
	--(*this);
	return oldpoint;
}
Point Point::operator+(const Point &p)const
{
     
	//创建一个临时无名对象并返回给调用者。
	return Point(this->x + p.x, this->y + p.y);
}
void Point::display() const
{
     
	cout << "(" << this->x << "," << this->y << ")" << endl;;
}
int main()
{
     
	int x1, y1, x2, y2;
	cout << "请输入P1点的x和y值:" << endl;
	cin >> x1 >> y1;
	cout << "请输入P2点的x和y值:" << endl;
	cin >> x2 >> y2;
	Point P1(x1, y1), P2(x2, y2);
	cout << "------P1,P2-----" << endl;
	P1.display();
	P2.display();
	cout << "------P1自增-----" << endl;
	cout << "P1++:";
	(P1++).display();
	cout << "++P1:";
	(++P1).display();
	cout << "------P2自增-----" << endl;
	cout << "P2++:";
	(P2++).display();
	cout << "++P2:";
	(++P2).display();

	cout << "------P1自减-----" << endl;
	cout << "P1--:";
	(P1--).display();
	cout << "--P1:";
	(--P1).display();

	cout << "------P2自减-----" << endl;
	cout << "P2--:";
	(P2--).display();
	cout << "--P2:";
	(--P2).display();

	cout << "------当前P1,P2-----" << endl;
	cout << "P1: ";
	P1.display();
	cout << "P2: ";
	P2.display();
	cout << "----重载+运算符的使用----" << endl;
	Point SumP3 = P1 + P2;
	cout << "SumP3: ";
	SumP3.display();
	return 0;
}

你可能感兴趣的:(C/C++语言,c++)