C++的运算符的重载的记录

整体感受

C++真的是门很怪的语言啊,很多的语言细节都不能掌握,只能说是很奇怪了。
以下所有内容,都是个人的看法,不是很全面,如果有相关的问题,请在下面留言哈,我再补充,谢谢。另一点就是所有的代码我贴的都是全部的代码,为了方便各位同学运行,但都不长。


对于运算符的重载,有以下以下几项注意点:
  1. 对于一个符号重载函数,在成员函数中,它的参数个数最多为一个,也就是说,成员函数重载的运算符的参数,可以为0个为1个,但是不可以为两个。

注:区别于全局运算符的重载,全局运算符重载函数的参数可以是两个。

咱们参数的个数,由少到多,依次说明,也就是从0个到1个。

  • 参数为0个

参数为0个,只有一种情况,就是重载++--这样的一元运算符,我们在之前了解过,C/C++对于类似这个++ 运算有前置与后置之后,如果是a++,那么我们先使用a的值,再另a自加,如果是++a,那么就是先让a自增,再使用a的值,但是这里有一点我们需要注意,它们的运算单元都是一个a,如果我们要重载类似于++这样的运算符时,如果区分我们重载的是前置运算符还是后置运算符呢?此时,我们的参数个数的作用就出现了,如果是前置运算符,则参数个数为0个,如果是后置运算符,会有一个参数。至于后置运算符有一个参数,我在文章的后面进行讲解。

现在我们有如下代码:

#include <iostream>
using namespace std;

class A{
	private:
		int _data;
	public:
		A(int n):_data(n){
			
		}
		
		A& operator++(){
			this->_data = this->_data+1;
			return *this;
		}
		
		void show(){
			cout << _data<<endl;
		}
};
int main(){
	A obj(1);
	++obj;				//(a)
	obj.show();
	return 0;
}

此时可以编译通过,输出2,如果将(a)处代码改为obj++后,将会报编译错误,如下:
在这里插入图片描述
则错误提示可处,如果使用obj++的话,我们需要在运算符重载的函数处添加一个参数,为 int。现在,我们再来实现++后置的重载运算方式,很容易的写出如下代码:

#include <iostream>
using namespace std;

class A{
	private:
		int _data;
	public:
		A(int n):_data(n){
			
		}
		
		A& operator++(){
			this->_data = this->_data+1;
			return *this;
		}
		
		A& operator++(int){  // (b)
			this->_data = this->_data+2;
			return *this;
		}
		
		void show(){
			cout << _data<<endl;
		}
};
int main(){
	A obj(1);
	obj++;
	obj.show();
	return 0;
}

(b)处即为我新添加的++后置重载运算符的代码,当我们运行后,可以发现obj中的_data已经变为3了,下面是运行结果的图示。
在这里插入图片描述
那么,我们可能会有一个疑问,当重载后置+++运算符时,它需要的一个参数int,可以变为其他类型的参数?还有就是它被传入的参数的值是什么啊?

现在我这里对于上面那两个问题 做出解决,第一个,除int外,我们不可以传递其他类型的参数。第二个,它被传入的值是0。我们可以做出如下代码,并运行。

#include <iostream>
using namespace std;

class A{
	private:
		int _data;
	public:
		A(int n):_data(n){
			
		}
		
		A& operator++(){
			this->_data = this->_data+1;
			return *this;
		}
		
		A& operator++(double n){		//(c)
			cout << n;
			this->_data = this->_data+2;
			return *this;
		}
		
		void show(){
			cout << _data<<endl;
		}
};
int main(){
	A obj(1);
	obj++;
	obj.show();
	return 0;
}

发现会报出一个编译错误 ,我对这个错误 进行了截图,发现编译器很清楚的告诉我们,后面的那个参数只可以是int,不能是其他类型的参数。
在这里插入图片描述
现在我们用代码对第二问题的答案给出解释,

#include <iostream>
using namespace std;

class A{
	private:
		int _data;
	public:
		A(int n):_data(n){
			
		}
		
		A& operator++(){
			this->_data = this->_data+1;
			return *this;
		}
		
		A& operator++(int n){		//(d)
			cout << n;
			this->_data = this->_data+2;
			return *this;
		}
		
		void show(){
			cout << _data<<endl;
		}
};
int main(){
	A obj(1);
	obj++;
	obj.show();
	return 0;
}

代码(d)处是我新添加修改的部分,经过编译运行后,它的结果如下。
在这里插入图片描述
结果为03,好像感到很奇怪,但其实一点了不用奇怪,前面的0是我们cout<<n;出现的结果,后面的3是调用show()函数的结果,结果显而意见,n的值是0

  • 参数为1个

咱们这里说明参数为1个的部分,我们举两个例子,分别是运算符+<<。咱们对于+的重载应该是比较熟悉的,所以,我们这里先拿+举例子,首先思考,对于平常写代码的时候,运算符+是怎么使用的?一般都是这样使用的吧 int a = 1+2;,可以很轻松的发现,一个加号运算符需要两个参数,分另是左运算数与右运算数,那么我们在重载的加号的时候,也需要满足它有两个参数。那么它的左运算数是调用它的对像,右运算数就是传入的参数。

我们编写代码如下:

#include <iostream>
using namespace std;

class A{
   private:
   	int _data;
   public:
   	A(int n):_data(n){
   		
   	}
   	
   	A& operator +(A& obj){     // (e)
   		cout <<"obj._data = " <<obj._data << endl;
   		this->_data = this->_data + obj._data;
   		return *this;
   	}
   	
   	void show(){
   		cout << _data<<endl;
   	}
};
int main(){
   A a1(1);
   A a2(2);
   A a3 = a1 + a2;
   a3.show();
   return 0;
}

它的运算如下图所示:
在这里插入图片描述
可以很明确的看出来,是对像a1调用了成员函数,并且它的成员对像为a2

我们再说一个特殊的运算的<<,对于这个运算符,它的特殊之处不在它的实现,而在于它的调用。我们把show ()函数修改一下,修改为<<的重载运算符,使其可以调用cout进行输出操作。
我们调用的代码如下:

#include <iostream>
using namespace std;

class A{
   private:
   	int _data;
   public:
   	A(int n):_data(n){
   		
   	}
   	
   	ostream& operator<<(ostream& os){
   		os <<"this->_data = " <<this->_data << endl;
   		return os;
   	}
};
int main(){
   A a2(2);
   a2<<cout; // (f)
   return 0;
}

它的输出结果如下所示:
在这里插入图片描述
可以看到,对像内的数据已经被成功输出了。但是它的调用方式,在代码处(d)所示,是一个很奇怪的调用方式,它的cout被放在了<<之后,其实他细分析一下,这样的也是有道理的,它的调用者是a2,传入的参数是cout,而cout又是被定义为一个流,所以也是可以得到的,但是它的写法却是让我们很不舒服,为了得到我们平时使用的方式,cout << a2;,我们可以使用全局的重载<<操作符,具体的就不在这里演示了,基本的思想还是一致的,寻找运算算的两个对像的运算数就可以了。


完!
posted @ 2020-02-16 19:37  老耗子  阅读(141)  评论(0编辑  收藏  举报