C++运算符重载+,前置++后置++,友员函数实现运算符重载的应用场景

为什么要有运算符重载?

一些用于自定义类型,编译器不知道如何进行类型的运算。

运算符重载的本质是函数。

用两种方法实现运算符重载:

1、重载为成员函数,解释为:ObjectL.operator op(ObjectR),左边操作数ObjectL通过this指针传递,右操作数由参数Object传递

2、重载为友员函数,解释为:operator op(ObjectL,ObjectR),左右操作数都有参数传递

二元操作符,复数类举例子:

	#include
	#include
	using namespace std;
	
	class Complex {
		friend Complex operator+(Complex &c1, Complex &c2);//友元函数实现运算符重载
		
	public:
		Complex() {
			this->a = 0;
			this->b = 0;
		}
		Complex(int a, int b) {
			this->a = a;
			this->b = b;
		}
		Complex operator+(const Complex &obj) {            //成员函数实现运算符重载
			Complex temp(this->a + obj.a, this->b + obj.b);
			return temp;
		}
		/*
		void operator=(const Complex &obj) {          //如果这样写的话,不支持连等c1=c2=c3
			this->a = obj.a;
			this->b = obj.b;
		}
		*/
		Complex & operator=(const Complex &obj) {     //如果这样写的话,支持连等c1=c2=c3
			this->a = obj.a;
			this->b = obj.b;
			return *this;
		}
		void print() {
			printf("a+bi=%d+%di\n", this->a, this->b);
		}
	protected:
	private:
		int a;//实部
		int b;//虚部
	};
	
	//友员函数实现加法
	Complex  operator+(Complex &c1,Complex &c2) {
		Complex c(c1.a + c2.a, c1.b + c2.b);
		return c;
	}
	
	void main() {
		Complex c1(1, 2), c2(3, 4);
		Complex c4 = c1 + c2;          //运算符重载
	
		Complex c5 = c1.operator+(c2); //成员函数运算符重载本质
		Complex c6 = operator+(c1,c2); //友员函数运算符重载本质
	
		c4.print();
		c5.print();
		c6.print();//以上三个结果相同
	
		Complex c7 = c1 + c2 + c4;     //为什么能链式编程,因为返回值为新的对象
		c7.print();
	
		Complex c8;
		c8 = c1=c7;                    //链式编程
		c7.print();
		
	}

一元操作符,前置和后置:

	#include
	#include
	
	using namespace std;
	
	class Time {
		friend void operator++(Time &t);//友员函数实现前置++运算符重载
		friend Time operator++(Time &t, int);
	public:
		
		Time() {
			this->day = 0;
			this->month = 0;
			this->year = 0;
		}
		Time(int day, int month, int year) {
			this->day = day;
			this->month = month;
			this->year = year;
		}
		/*
		void operator++() {   //成员函数实现前置++运算符重载
			this->day += 365;
			this->month += 12;
			this->year++;
		}
		
		Time operator++(int) {//成员函数实现后置++运算符重载
			Time temp = *this;
			this->day += 365;
			this->month += 12;
			this->year++;
			return temp;       //这里需要注意两个地方,
			                   //第一int占位,代表后置++,第二记得返回没加之前的值,这是后置++语义决定的。
		}
		*/
		void print() {
			printf("year:%d month:%d day:%d\n", this->year, this->month, this->day);
		}
	protected:
	private:
		int year;
		int month;
		int day;
	};
	
	void operator++(Time &t) {//友员函数实现前置++运算符重载
		t.day += 365;
		t.month += 12;
		t.year++;
	}
	Time operator++(Time &t, int) {
		Time temp = t;
		t.day += 365;
		t.month += 12;
		t.year++;
		return temp;       //这里需要注意两个地方,
		                   //第一int占位,代表后置++,第二记得返回没加之前的值,这是后置++语义决定的。
	}
	void main() {
		Time t;
		++t;
		t.print();
		t++;
		t.print();
	}

既然成员函数可以实现运算符的重载,那么为什么还需要友员函数呢?
接下来介绍友员函数运算符重载的应用场景

	#include
	#include
	#include
	using namespace std;
	
	class Com {
	public:
		friend ostream & operator<<(ostream &out, Com &c);
		Com(int a, int b) {
			this->a = a;
			this->b = b;
		}
		void print(char *p) {
			
			cout << p << endl;
			cout << "a:" << this->a << " b:" << b << endl;
		}
	private:
		int a;
		int b;
	};
	ostream & operator<<(ostream &out, Com &c) {
		out << "a:" << c.a << " b:" << c.b << endl;
		return out;
	}
	
	void  f() {
		Com c(1, 2);
		
		//全局函数
		cout << c;
		//operator<<(cout, c);
		//没有方法拿到cout这个类的编码,只能用友员函数
		//cout.operator(c);//这才是真正的类成员函数,但是这是表准里写好的,没办法给人家
		//添加一个方法,所以这个时候,只能采用友员函数啦
	
		//函数返回值当左值,要求返回一个引用
	    /*
		cout << c << "abc";
	
		s cout.operator<<(c);
		s.operator<<("abc");
	    */
		cout << c << "abc";
	}

你可能感兴趣的:(C++,计算机基础,运算符重载,前置++,后置++,友元函数实现运算符重载)