2020.11.4 第5节 C++运算符重载

2020.11.4 第5节 C++运算符重载

一、基本运算符重载


	1.为什么有运算符重载
		想要直接操作使用运算符去操作对象 赋予运算符新的含义,操作自定义类型
	2.运算符重载的分类
		2.1 友元重载
			参数个数=操作数
		2.2 类重载
			参数个数=操作数-1    代表对象的行为
		2.3 流运算符重载     输入输出流
		2.4 特殊运算符的重载
	3.运算符重载实质:函数调用
		函数返回值类型 函数名(函数参数)
		{
			函数体;
		}
		函数名:operator 加上运算符组成函数名

#include <iostream>
using namespace std;
class MM
{
public:
	MM(string name, int score):name(name), score(score){}
	//MM:函数返回值类型
	//opetator+: 函数名
	void print()const
	{
		cout << name << ":" << score << endl;
	}
	//友元函数的方式
	friend MM operator+(MM mm1, MM mm2);
	//成员函数的方式
	//mm1-mm2 mm1.operator-(mm2);
	MM operator-(MM mm)
	{
		MM object(this->name, this->score - mm.score);
		return object;
	}
protected:
	string name;
	int score;
};
MM operator+(MM mm1, MM mm2)
{
	MM object(mm1.name, mm1.score * 0.4 + mm2.score * 0.6);
	return object;
}
int main()
{
	int a = 0;
	int b = 1;
	int sum = a + b;
	MM mm1("baby", 68);	
	MM mm2("baby", 99);
	//解析为 mm1+mm2:opetator+(mm1,mm2);
	MM mm = mm1 + mm2;	//自定义类型,需要剥洋葱  mm1+mm2
	mm.print();
	
	//cin >> mm1;
	//string str;
	//cin >> str;			//运算符重载
	//mm2-mm1  mm2.opetator(mm1);
	MM result = mm2 - mm1;
	result.print();
	result = mm1 - mm2;
	result.print();
	return 0;
}

二、从string上看重载


习惯:
单目:成员函数的方式重载
双目:友元方式重载
	必须使用成员函数: () [] -> = >> <<
					.  .* :: ?: 这些不能被重载

#include <iostream>
#include <cstring>
#include <string>
using namespace std;
class myString
{
public:
	myString(const char* str)
	{
		this->str = new char[strlen(str) + 1];
		strcpy(this->str, str);
	}
	//myString(myString& object)
	//{
	//	this->str = new char[strlen(object.str) + 1];
	//	strcpy(this->str, object.str);
	//}
	int size() const
	{
		return strlen(str) + 1;
	}
	//必须使用成员函数对象: () [] -> >> <<
	//对象[index] 对象.operator[](index);
	char& operator[](int index)
	{
		return str[index];
	}
	bool operator<(myString object)
	{
		return strcmp(this->str, object.str) < 0;
	}
	friend  bool operator>(myString str1, myString str2);
	//习惯:
	//单目:成员函数的方式重载 单目操作符 也就是只接受一个操作数的操作符
	//双目:友元方式重载
protected:
	char* str;
};

// ()重载
class Sum
{
public:
	Sum():num(100){}
	int operator()()
	{
		return num;
	}
protected:
	int num;
};
void printSum(int num)
{
	cout << num << endl;
}
bool operator>(myString str1, myString str2)
{
	return strcmp(str1.str, str2.str) > 0;
}
int main()
{

	string str1 = "Loveyou";
	string str2 = "Imissyou";
	cout << (str1 > str2) << endl;     //bool类型
	cout << (str1 < str2) << endl;
	cout << str1[1] << endl;
	//对象[index] 需要重载
	//只有对象[index]返回变量,str1[0]='X' 才能成立
	str1[0] = 'X'; //str1.str[0]='X';
	for (int i = 0; i < str1.size(); i++)
	{
		cout << str1[i];
	}
	cout << endl;
	myString myStr1 = "Loveyou";
	myString myStr2 = "Imissyou";
	cout << (myStr1 > myStr2) << endl;
	cout << (myStr1 < myStr2) << endl;
	myStr1[0] = 'X';
	for (int i = 0; i < myStr1.size(); i++)
	{
		cout << myStr1[i];
	}
	cout << endl;
	//Sum arrayNum(123);
	//arratNum.operator() ();
	//仿函数
	//arrayNum();			//实现打印
	printSum(Sum()());
	return 0;
}

三、++运算符的重载

#include <iostream>
#include <string>
using namespace std;
class Num
{
public:
	Num(int num):num(num){}
	void print()
	{
		cout << num << endl;
	}
	Num operator++()
	{
		cout << "前置++"<<endl;
		this->num++; //++this->num;
		return (*this);
	}
	//后置++引入了一个标记,参数int
	Num operator++(int)			//后置++:先运算 后自增
	{
		cout << "后置运算符" << endl;
		Num object(this->num);
		this->num++;
		return object;
	}
protected:
	int num;
};
int main()
{
	Num value(10);
	//value++;
	++value; //value+1;
	value.print();
	value++.print();
	value.print();
	return 0;
}

四、流运算符的重载


流运算符重载 左移 右移
简化打印
	 自己写的类也能实现效果,没必要都展开
	cin:	>>	istream类       输入流对象
	cout:  <<	ostream类       输出流对象
	1.流重载必须是友元
	2.流重载尽量用&

#include <iostream>  //iostream 流类体系
#include <string>
using namespace std;

class Data
{
public:
	Data(string name, int age, int num) :name(name), age(age), num(num){}
	friend istream& operator>>(istream& object, Data& data);  // 输入流返回输入流对象
	friend ostream& operator<<(ostream& object, Data& data);
protected:
	string name;
	int age;
	int num;
};
istream& operator>>(istream& in, Data& data)  // 输入流返回输入流对象
{
	//in等效为cin
	in >> data.name >> data.age >> data.num;
	//返回cin 
	return in;
}
ostream& operator<<(ostream& out, Data& data)
{
	//out等效cout
	out << data.name << ":" << data.age << ":"<<data.num;
	//返回cout
	return out;
}
class MM
{
public:
	MM(){}
	friend void operator>>(istream& in, MM& mm)
	{
		//传cin
		in >> mm.name >> mm.age;
	}
	//out=cout mm等于实参
	friend void operator<<(ostream& out, MM mm)
	{
		//传cout
		//cout<<mm.name<<mm.age;
		out << mm.name << mm.age;
	}
protected:
	string name;
	int age;
};
int main()
{
	string str = "Iloveyou";
	//cin.operator>>(str);  别人写的 只能友元
	cin >> str;
	cout << str;
	Data myData("MM", 18, 1001);
	cout << myData << endl;
	cin >> myData;					//流重载 返回的是一个流对象
	cout << myData << endl;
	cout << 1 << 2 << 3 << endl;  //cout流对象

	MM mm;
	//operator>>(cin,mm);    函数名(函数参数)
	cin >> mm;					//mm自定义类型 
	//opetator<<(cout,mm);
	cout << mm;				// opetator<<(cout,mm); 函数名(函数参数)
	//cout << mm << 1 << endl;  为啥报错

	return 0;
}

五、对象加常量


	1.类中类的访问
	2.运算符重载特殊用法

#include <iostream>
using namespace std;
class MM
{
public:
	MM(int data):data(data){}
	void print()
	{
		cout << data << endl;
	}
	friend MM operator+(MM one, MM two)
	{
		return MM(one.data + two.data);
	}
	MM operator + (MM object)
	{
		return MM(this->data + object.data);
	}
protected:
	int data;
};
class A
{
public:
	class B			//B是受A权限限定,如果不是public属性,类外不能访问
	{
	public:
		B(int b):b(b){}
		int& getB()
		{
			return b;
		}
	protected:
		int b;
	};
};
int main()
{
	A::B object(13);	//类中的属性只能通过对象访问
	object.getB() = 100;
	A a;
	//运算符重载操作普通数据和对象运算符
	MM mm(13);
	
	MM result = 1 + mm;		//1.operator+(mm); 只能友元
	//   形参 传参 强制类型转换
	//result = mm + 1;		//mm.operator+(1); 成员函数 友元 都可以
	result.print();
	 
	return 0;
}

六、作业

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值