C++(9)运算符重载

即:对已有的运算符重新进行定义,富裕其另外一种功能,以适应不同的类型运算

加法(减法)运算法重载

比如 加法 + ,基本的类型,int,float等,编译器是知道如何计算的。

但是,对于自定义类或者其他高级点的类型时,编译器就不知道“+”运算法该如何操作了,这是就可以使用运算法重载的操作。

  • 通过成员函数重载 + 号
class Person
{
public:
	//成员函数重载+号
	Person operator+(Person &a)
	{
		Person temps;
		temps.m_A = this->m_A + a.m_A;
		temps.m_B = this->m_B + a.m_B;
		return temps;
	}

	int m_A;
	int m_B;
};

void test()
{
	Person p1;
	Person p2;
	p1.m_A = 10;
	p2.m_A = 10;
	p1.m_B = 10;
	p2.m_B = 10;
	//成员函数重载本质运行:
	Person p3 = p1.operator+(p2);
	//简化
	Person p4 = p1 + p2;
}
  • 通过全局函数重载 + 号
class Person
{
public:
	//成员函数重载+号
	/*Person operator+(Person &a)
	{
		Person temps;
		temps.m_A = this->m_A + a.m_A;
		temps.m_B = this->m_B + a.m_B;
		return temps;
	}*/

	int m_A;
	int m_B;
};

Person operator+(Person &a, Person &b)
{
	Person tempss;
	tempss.m_A = a.m_A + b.m_A;
	tempss.m_B = a.m_B + b.m_B;
	return tempss;
}

void test()
{
	Person p1;
	Person p2;
	p1.m_A = 10;
	p2.m_A = 10;
	p1.m_B = 10;
	p2.m_B = 10;
	//成员函数重载本质运行:
	//Person p3 = p1.operator+(p2);
	//简化
	//Person p4 = p1 + p2;
	//全局函数重载本质:
	Person p5 = operator+(p1, p2);
	//简化
	Person p6 = p1 + p2;
}
  • 符号进行函数重载
Person operator+(Person &a,int num)
{
	Person tempss;
	tempss.m_A = a.m_A + num;
	tempss.m_B = a.m_B + num;
	return tempss;
}

左移运算法重载 <<

同样可以分为,成员函数重载 和 全局函数重载

一般 不用 成员函数重载 左移运算法

一般 采用 全局函数重载 左移运算法

class Person
{
public:

	int M_A;
	int M_B;

};
//重载左移运算法
ostream & operator<<(ostream &cout, Person &p)
{
	cout << "" << p.M_A << "" << p.M_B;
	return cout;
}
void test()
{
	Person p;
	p.M_A = 10;
	p.M_B = 10;
	cout << p << endl;
}

关于这个部分需要详细说明一下:

//重载左移运算法
ostream & operator<<(ostream &cout, Person &p)
{
	cout << "" << p.M_A << "" << p.M_B;
	return cout;
}

cout 在编译器中的标准定义中没有输出 类 的功能,所以对其进行重载,而全局函数涉及到对 cout 的新定义,从 std 定义中可以看到,cout 本身属于 ostream 类型,并采用 引用创新的名,防止重名,采用ostream 作为返回类型,采用引用,就是为了对最初的那个cout进行操作,如果不加&,它就会返回一个新的,所以采用 &这样 使用 endl 就不会报错了。

针对 类的私有变量的操作,可以配合友元函数进行操作:

#include <iostream>
using namespace std;
class Person
{	//使重载函数变成友元
	friend ostream & operator<<(ostream &cout, Person &p);
public:
	Person(int a, int b)
	{
		M_A = a;
		M_B = b;
	}
private:
	int M_A;
	int M_B;
};
//重载左移运算法
ostream & operator<<(ostream &cout, Person &p)
{
	cout << "" << p.M_A << "" << p.M_B;
	return cout;
}
void test()
{
	Person p(10,10);
	cout << p << endl;
}

递增运算法重载 ++

#include <iostream>
using namespace std;
class Person
{
	//使重载函数变成友元
	friend ostream & operator<<(ostream &cout, Person &p);
public:
	Person(int a, int b)
	{
		M_A = a;
		M_B = b;
	}
	//前置重载递增运算法,对自身属性进行操作不需要参数
	//为啥使用 & , 这是为了当进行多次递增时,重载的对象都是最初的那个,如果不加&,会出现,没进行一次操作就又创建一个新的对象的情况
	Person& operator++()
	{
		M_A++;
		return *this;//返回类本身
	}
private:
	int M_A;
	int M_B;
};
//重载左移运算法
ostream & operator<<(ostream &cout, Person &p)
{
	cout << "" << p.M_A << "" << p.M_B;
	return cout;
}
void test()
{
	Person p(10,10);
	cout << ++p << endl;
}
  • 前置重载递增运算法,对自身属性进行操作不需要参数
  • 为啥使用 & , 这是为了当进行多次递增时,重载的对象都是最初的那个,如果不加&,会出现,没进行一次操作就又创建一个新的对象的情况 》》链式编程
Person& operator++()
{
	M_A++;
	return *this;//返回类本身
}
  • 重载后置 ++ 运算
  • 这里加上 int 采用,int 作为占位参数,可以用于区分前置和后置
  • 后置递增就是:
  • : 记录当前结果; 递增;最后 记录结果返回
  • 这里不能使用 引用 &,因为本身后置递增时返回的是递增前的数值,就是说函数返回是递增前的数值,如果使用了引用 ,引用改变了,原来的数值也会改变,所以不符合后置递增的思想
//后置递增
	Person operator++(int) //使用 int 作为占位参数,用于让编译器区分后置还是前置
	{
		Person temp = *this;//先记录当前值
		M_B++;//在进行递增
		return temp;//最后返回原来值
	}
//全局函数:此时返回变量
ostream & operator<<(ostream &out, Person xx)
{
	out << xx.M_B;
	return out 
}

需要注意,如果使用前面的 的左移运算的重载ostream & operator<<(ostream &out, Person &p)
在输出后置递增时,就不能直接使用 cout << p++<< endl;,因为返回类型不同,一个返回的是引用,一个返回是的变量

赋值运算符重载 =

C++ 编译器至少提供给我们的四个函数:

  • 构造函数
  • 析构函数
  • 拷贝构造函数
  • 赋值运算符 operator= (但是这个操作就是见到的浅拷贝操作,释放堆区时还是会出现浅拷贝的问题)
    所以可以通过重载来对 = 进行深拷贝的操作。
//赋值运算符重载
class Temp
{
	friend void test2();
public:
	Temp(int a)
	{
		m_A = new int(a);
	}
	~Temp()
	{
		if (m_A !=NULL)
		{
			delete(m_A);
			m_A = NULL;
		}
	}
	//返回引用还是为了应对对此赋值
	Temp& operator=(Temp &p)
	{
		//深拷贝操作
		this->m_A = new int(*p.m_A);
		return *this;
	}
private:
	int *m_A;
};
void test2()
{
	Temp T1(10);
	Temp T2(20);
	Temp T3(30);
	T3 = T2 = T1;//赋值
	cout << *T1.m_A << "  " << *T2.m_A << "  " << *T3.m_A << endl;
}
int main()
{
	test2();
}

关系运算符重载 ==, !=,>,<, >=,<=等

//重载关系运算符
	//赋值运算符重载
class Temp
{
	friend void test2();
public:
	Temp(int a)
	{
		m_A = new int(a);
	}
	~Temp()
	{
		if (m_A !=NULL)
		{
			delete(m_A);
			m_A = NULL;
		}
	}
	//重载关系运算符
	bool operator==(Temp &T)
	{
		if (this->m_A == T.m_A)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	//返回引用还是为了应对对此赋值
	Temp& operator=(Temp &p)
	{
		//深拷贝操作
		this->m_A = new int(*p.m_A);
		return *this;
	}

private:
	int *m_A;
};

函数调用运算符重载 ()

class Temp
{
public
//重载 括号(),也就是仿函数,还可以有返回类型
	void operator()(string str)
	{
		cout << str << endl;
	}
}
void test3()
{
	Temp P;
	P("hello world");
}

重载 对 自定义类型 强制转换

class Fraction
{
	public:
		Fraction(int num, int den=1): m_numberator(num), m_denominator(den){}
		//重载了对自定义类型的double()操作,const,看情况加,强制转换这里不需要有返回值类型,返回值类型就是double这里
		operator double() const {
			return (double)(m_numberator /m_denominator);
		}
	private:
		int m_numberator;
		int m_denominator;
};

....

Fraction f(3,5);
double d = 4 + f;//此时f就是返回0.6 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LionelMartin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值