栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++笔记 06 (运算符重载)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++笔记 06 (运算符重载)

一. 运算符重载

对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。

1. 加号运算符重载

作用:实现两个自定义数据类型相加的运算

class Person
{
	public:
		Person(){};
		Person(int a,int b)
		{
			this->m_A=a;
			this->m_B=b;
		}

		//成员函数实现加号运算符重载
		Person operator+ (const Person &p)
		{
			Person temp;
			temp.m_A=this->m_A+p.m_A;
			temp.m_B=this->m_B+p.m_B;
			return temp;
		}
	public:
		int m_A;
		int m_B;
};

//全局函数实现加号运算符重载
Person operator+ (const Person &p1 ,const Person &p2)
	{
		Person temp(0,0);
		temp.m_A=p1.m_A+p2.m_A;
		temp.m_B=p1.m_B+p2.m_B;
		return temp;
	}

//运算符重载可以发生函数重载
Person operator+ (const Person p2,int val)
{
	Person temp;
	temp.m_A=p2.m_A+val;
	temp.m_B=p2.m_B+val;
	return temp;
}

void test()
{
	Person p1(10,10);
	Person p2(20,20);

	// 成员函数方式
	Person p3=p1+p2;//相当于p2.operator+(p1)
	cout<<"m_A:"<
	... ...
}

总结1: 对于内置的数据类型的表达式的运算符是不可能改变的
总结2:不能滥用运算符重载(例如operator+函数中写成减法)

2. 左移运算符重载

作用:可以输出自定义数据类型

class Person
{
	friend ostream & operator <<(ostream & out ,Person &p);
	public:
		Person(int a,int b)
		{
			this->m_A = a;
			this->m_B = b;
		}
		//成员函数实现不了, p<
	out<<"a:"<
	Person p1(10,20);
	cout<
	... ...
}

总结:重载左移运算符配合友元可以实现输出自定义数据类型

3. 递增运算符重载
int a=10;
cout<<++a< 
//前置递增与后置递增的区别

int main()
{
	int a=10;
	a++; //等价于a=a+1
	cout< 
class MyInteger
{
	friend ostream& operator <<(ostream& out,MyInteger myint);

	public:
		MyInteger()
		{
			m_Num=0;
		}
		
	//前置++
	MyInteger & operator++() 
	{
		//先++
		m_Num++;
		//再返回
		return *this;
		
		
	}
	

	//后置++
	MyInteger operator++(int)
	{
       //int代表占位参数,可以用于区分前置和后置递增

	  //先记录当时结果,后递增,最后将记录结果做返回
	  MyInteger temp=*this; 
	  m_Num++;
	  return temp;
	}
	private:
		int m_Num;
};

ostream & operator <<(ostream &out,MyInteger myint)
{
	out<
	MyInteger myint;
	cout<<++myInt<
	MyInteger myInt;
	cout<... ...}

总结:前置递增返回引用,后置递增返回值

4. 赋值运算符重载

C++编译器至少给一个类添加4个函数
1)默认构造函数(无参,函数体为空)
2)默认析构函数(无参,函数体为空)
3)默认拷贝构造函数,对属性进行值拷贝
4)赋值运算符operator=,对属性进行值拷贝

如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题

class Person
{
	public:
		Person (int age)
		{
			//将年龄数据开辟到堆区
			m_Age= new int(age);
		}
		//重载赋值运算符
		Person & operator =(Person &p)
		{
			if(m_Age!=NULL) //先判断是否有属性在堆区,如果有先释放干净,然后再深拷贝
			{
				delete m_Age;
				m_Age=NULL;
			}
			//编译器提供的代码是浅拷贝 即m_Age=p.m_Age;
			//提供深拷贝,解决浅拷贝的问题
			m_Age= new int(*p.m_Age);
			//返回自身
			return *this;
		}
		~Person()
		{
			if(m_Age!=NULL) 
			{
				delete m_Age;
				m_Age=NULL;
			}
		}
		//年龄的指针
		int *m_Age;
}

void test01()
{
	Person p2(20);
	Person p3(30);
	p3=p2=p1; //赋值操作
	cout<<"p1的年龄为:"<<*p1.m_Age<... ...}
5. 关系运算符重载

作用:重载关系运算符,可以让两个自定义类型对象进行对比操作

bool operator ==(Person &p)
{
	if(this->m_Nane==p.m_Name && this->m_Age==p.m_Age)
	{
		return true;
	}
	else
	{
		return false;
	}
}
bool operator !=(Person &p)
{
	if(this->m_Nane==p.m_Name && this->m_Age==p.m_Age)
	{
		return false;
	}
	else
	{
		return true;
	}
}
6. 函数调用运算符重载

1)函数调用运算符()也可以重载
2)由于重载后使用的方式非常向函数的调用,因此称为仿函数
3)仿函数没有固定写法,非常灵活

class Myprint
{
	public:
		void operator()(string test)
		{
			cout<
	//重载()操作符也称为仿函数
	Myprint myFunc;
	myFunc("hello"); 
}
class Myadd
{
	public:
		int operator()(int v1,int v2)
		{
			return v1+v2;
		}	
};
void test02()
{
	Myadd add;
	int ret=add(10,10)
	cout<<"ret="<...  ...}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1000717.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号