操作符重载

操作符重载规则

  • 不能被重载的操作符
符号符号举例
.Peron.name
.*Person.*name=*(Person.name)
::作用域操作符
?:条件操作符
  • 操作符重载不能改变操作数的个数
  • 操作符重载不改变运算顺序(依然先算 * / 后算+ -)
  • 操作符重载不改变运算的结合性
  • 操作符重载不能有默认参数
  • 操作符重载至少要有一个自定义类型
  • 操作符重载应当与原来操作符含义相似
  • 操作符重载可以是类的成员函数、类的友元函数、还可以是普通函数


单目运算符

++(左)

  • 说明: ++(左)可以进行连+

class Point
{
//friend Point& operator++(Point& p);
public:
	
	Point(int x, int y)
	{
		m_x = x;
		m_y = y;
	}
	
	Point& operator++()
	{
		++m_x ;
		++m_y ;

	  return *this;
	}

	void Print()
	{
		cout << "(" << m_x << " " << m_y << ")" << endl;
	}
private:
	int m_x;
	int m_y;
};

//Point& operator++(Point& p)
//{
//	++p.m_x;
//	++p.m_y;

//	return p;
//}

int main(void)
{
	Point A(1, 0);
	Point B(2, 2);

	++++A; 
	
	A.Print();//(3 2)
	
    return 0;
}

++(右)

  • 说明:++(右)不能进行连+
#include "stdafx.h"
#include <iostream>
using namespace std;

class Point
{
//	friend const Point operator++(Point& p, int);
public:
	
	Point(int x, int y)
	{
		m_x = x;
		m_y = y;
	}
	
	const Point operator++(int) //因为不能连+的,所以加个const
	{
		Point tmp = *this;
		m_x++;
		m_y++;
		return tmp;
	}

	void Print()
	{
		cout << "(" << m_x << " " << m_y << ")" << endl;
	}
private:
	int m_x;
	int m_y;
};


//const Point operator++(Point& p, int) //返回的是临时变量,所以不能返回引用
//{
//	Point tmp = p;
//	p.m_x++;
//	p.m_y++;
//	return tmp;
//}


int main(void)
{
	Point A(1, 0);
	Point B(2, 2);


	A++;	
	A.Print(); //(2 1)
	
    return 0;
}



双目操作符重载

  • 重载写法两种:
operator+(L,R)   //全局
L.operator+(R)  //成员函数


+ 运算符

  • 举例:重载+操作符:将两个类相加(对应的成员变量相加)

写法1:全局函数,在类中申明为友元

#include "stdafx.h"
#include <iostream>
using namespace std;

class Point
{
//friend Point operator+(Point& p1, Point& p2);
public:	
	Point(int x, int y)
	{
		m_x = x;
		m_y = y;
	}	
	
	Point operator+(Point& p2) //定义为成员函数,禁止返回局部变量或者它的引用
	{
		Point tmp(this->m_x + p2.m_x, this->m_y + p2.m_y);
		return tmp;
	}
	
	void Print()
	{
		cout << "(" << m_x << " " << m_y << ")" << endl;
	}
private:
	int m_x;
	int m_y;
};

//Point operator+(Point& p1,Point& p2) //重载+操作符,在Point类里面申明为友元,禁止返回局部变量或者它的引用
//{
//	Point tmp(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
//	return tmp;
//}


int main(void)
{
	Point A(1, 0);
	Point B(2, 2);

	Point C = A+B;  //全局显式: operator+(A,B)      //成员函数显式:A.operator+(B)
	C.Print();
	
	
    return 0;
}


+=运算符

#include "stdafx.h"
#include <iostream>
using namespace std;

class Point
{
	friend Point& operator+=(Point& p1, Point& p2); //申明全局为友元
public:
	
	Point(int x, int y)
	{
		m_x = x;
		m_y = y;
	}
	
	//Point& operator+=(Point& p2)  //或者申明成员函数
	//{
	//	m_x += p2.m_x;
//		m_y += p2.m_y;

//		return *this;
//	}
	void Print()
	{
		cout << "(" << m_x << " " << m_y << ")" << endl;
	}
private:
	int m_x;
	int m_y;
};


Point& operator+=(Point& p1, Point& p2)
{
	p1.m_x += p2.m_x;
	p1.m_y += p2.m_y;

	return p1;
}

int main(void)
{
	Point A(1, 0);
	Point B(2, 2);

	(A+=B)+=B; 
	A.Print();
	
    return 0;
}




<<  >> 运算符

  • 注意: >> 也不能写在成员函数内,只能写成全局函数
#include "stdafx.h"
#include <iostream>
#include "person.h"

using namespace std;


class Point
{
friend	ostream& operator<<(ostream& os, Point& p);
public:
	
	Point(int x, int y)
	{
		m_x = x;
		m_y = y;
	}

//	ostream& operator<<(ostream& os) <<操作符禁止写成员函数,否则调用变成: A << cout , 改变本意
//	{
	//	os << "(" << m_x << " " << m_y << ")";
	//	return os;
	//}
private:
	int m_x;
	int m_y;
};


ostream& operator<<(ostream& os, Point& p)
{
	os << "(" << p.m_x << " " << p.m_y << ")" ;
	return os;
}



int main(void)
{
	Point A(1, 0);
	Point B(2, 2);

	cout << A << B << endl; 
	
    return 0;
}



  • 注意: >> 也不能写在成员函数内
#include "stdafx.h"
#include <iostream>
using namespace std;

class Point
{
friend	istream& operator>>(istream& is, Point& p);
public:
	
	Point(int x, int y)
	{
		m_x = x;
		m_y = y;
	}

	void Print()
	{
		cout << "(" << m_x << "," << m_y << ")" << endl;
	}
private:
	int m_x;
	int m_y;
};



istream& operator>>(istream& is, Point& p)
{
	cout << "a:";
	is >> p.m_x;
	cout << "b:";
	is >> p.m_y;

	return is;
}


int main(void)
{
	Point A(1, 0);
	Point B(2, 2);

	 cin >> A >> B;
	
	 A.Print();
	 B.Print();
	 
    return 0;
}


= 运算符

#include "stdafx.h"
#include <iostream>
#include <string.h>

using namespace std;


class Student
{
public:
	Student()  //无参构造
	{
		m_id = 0;
		m_name = NULL;
	}

	Student(int id, const char name[]) //有参构造
	{
		m_id = id;
		int length = strlen(name);
		m_name = new char[length + 1];
		strcpy_s(m_name,length+1,name);
	}

	Student(const Student& another)  //拷贝构造
	{
		m_id = another.m_id;
		int length = strlen(another.m_name);
		m_name = new char[length + 1];
		strcpy_s(m_name, length + 1, another.m_name);
	}

	Student& operator=(const Student& another)  //=操作符重载,三件事
	{
		if(this==&another) return *this;//1. 防止自身赋值
		
		m_id = another.m_id;
		if (m_name != NULL)   //2. 判断是否为空,不为空,先释放
		{
			delete[]m_name;
			m_name = NULL;
		}

		int length = strlen(another.m_name); //3. 开辟内存
		m_name = new char[length + 1];
		strcpy_s(m_name, length + 1, another.m_name);

		return *this;
	}


	void Print()
	{
		cout << m_name << ": " << m_id << endl;
	}

	~Student()
	{
		if (m_name != NULL)
		{
			delete[] m_name;
			m_name = NULL;
		}
	}
private:
	int m_id;
	char* m_name;
};



int main(void)
{
	Student A (1, "julian");

	Student B (2, "mark");

	Student C (3, "kerr");

	C =A =B;
	C.Print(); //mark: 2


    return 0;
}



不建议重载 && 和 ||

  • 在已有的运算结构中 &&和 || 都有短路现象:if(a&&(a=1)) 如果a是0,那么后面(a=1)应该不执行,结果还是0,但是当你重载&&的时候: object.operator&&(t1), t1作为参数传进去,肯定是执行的,所以不会发生短路现象,但是有时候需要重载又不关心短路现象的时候可以进行重载


( ) 的重载

  • 重载()叫做仿函数,调用形式和函数类似
class Sqr
{
public:
	Sqr(int a)
	{
		this->a = a;
	}

	//想把s对象 定义成一个 带有一个参数的函数, 求出平方返回
	//此函数功能就是 对a求平方
	int operator()(int a)
	{
		return a*a;  //这个a和成员变量无关
	}
private:
	int a;
};


int main()
{
	Sqr A(3); //定义Sqr的对象A
	A(2); //求2的平方,返回4
}


-> 和 * 的重载

参考智能指针章节

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值