(9)C++运算符重载


运算符重载


认识
由来:对象不能相加 类里面多个成员,不知道谁加谁
而运算符重载就可以使对象相加,运算符可自定义
1.关键字:operator
2.本质是函数
例如:

class Cstu
{
public:
	int a;
	float b;
	Cstu()
	{
		a = 12;
		b = 12.5;
	}

};
//运算符重载
void operator+(Cstu &stu,int c)  //加上引用,避免拷贝构造  
 //假如成员stu与12相加  参数列表内是相加的两个数
{
	//可自定义类内的哪个成员和c相加
	cout << (stu.a + c) << endl;
}
int main()
{
	Cstu stu;
	stu + 12;  //调用运算符重载的函数
	//与参数列表里参数的位置对应
	system("pause");
	return 0;
}

注意:
(1)参数必须有一个包含类的参数或类类型的形参 加上&避免拷贝构造
(2)可以重载
返回值
1.作用:可以进行连续运算

//调用时stu + 12 是两个参数,连续运算就要返回值了 
	stu + 12 + 13;

代码如下:

int operator+(int d, Cstu&stu)
{
	return (12 + stu.a); //将相加的作为int值输出
}
//主函数调用
	cout << (12 + stu.a + 13) << endl; //int 值就可以加13了

当有多个运算符重载函数时

	int operator+(Cstu& stu, int c)   
{
	return (stu.a + c);
}
	int operator+(int d, Cstu&stu)
{
	return (d + stu.a);
}
Cstu& operator+(Cstu&stu, Cstu&stu1)
{
	stu.a += stu1.a;  //stu里的a进行改变
	return (stu );
}
//主函数输出
	cout << 12 + stu.a + 13 + (stu1 +stu) + stu1; //连续输出

注意:输出时可以用优先级进行改变,不过要注意能否进行相加

运算符在类内重载
1.类内只写一个整数就可以
原因:参数有隐含的this指针,指向函数外类内的内容 即类+a
而如果用a+类,类内的运算符重载函数就实现不了了


class Cstu
{
public:
	int age;
	Cstu()
	{
		age = 12;
	}
	int operator+(int a) //类内只写一个整数就可以
	//原因:1.参数有隐含的this指针,指向函数外类内的内容 即类+a
	{
		return (age + a);
	}
};

注意:
1.类内的运算符重载,左操作数必须是对象,a+类 只能写类外
2.只能重载有效的运算符,例如@就不能重载
3.下面是能重载的注意点
a.=、[]、()、->必须是成员
b.复合赋值运算符,通常是成员:+=、-=、<<(右移)
c.改变对象状态的运算符,如递增,解引用,通常是成员(因为int a;a++;这样的系统已经定义好了)
d.算术,关系,位运算符,最好非成员
运算符重载例子

算术运算符:+、-、*、%、/
关系运算符:!=、==、<=、>=
位运算符:^、&、|
逻辑运算符:&&、||

二元运算符

class Cstu
{
public:
	int a;
	Cstu(int age)
	{
		a = age;
	}
};
int operator >= (Cstu &stu1,Cstu &stu2)
{
	return (stu1.a >=stu2.a );
}
//主函数调用
	Cstu stu1(12);
	Cstu stu2(13);
	cout << (stu1.a >= stu2.a);

一元运算符

!,+,-,&,*,~等

class Cstu
{
public:
	int a;
	Cstu(int age)
	{
		a = age;
	}
};
int operator - (Cstu stu3)
{
	return(-stu3.a);
}
//主函数调用
	cout << (-stu3.a );

输入输出运算符重载

cin,cout也是对象
cin是istream的对象
cout是ostream的对象

ostream
参数一是ostream引用,参数二是对象的常引用

class Cstu
{
public:
	int age;
	Cstu()
	{
		age = 12;
	}
};
void operator << (ostream &out,  Cstu &stu)
{
	out << stu.age ;
}
//主函数调用
	Cstu stu;
	cout << stu;  //cout赋给out,stu赋给stu执行函数

但如果想要连续输出
cout << stu << stu;就要有返回值了
过程:
先调用左边的cout << stu
返回了void,再执行右边时就成了void <<stu;
所以就要用ostream&来作为返回值,返回定义的输出out就可以了
代码如下:

ostream& operator << (ostream &out,  Cstu &stu)
{
	out << stu.age ;
	return out;  //这样就可以连续输出了
}

注意:
(1)由于左侧是ostream 所以不能放类内
(2)由于数据成员一般都是私有的所以就要借助友元
常用的成型代码如下:

#include<iostream>
using namespace std;
class Cstu
{
private:  //数据成员私有
	int age;
public:
	Cstu()
	{
		age = 12;
	}
	//友元使运算符重载函数可见
	friend ostream& operator << (ostream &out, Cstu &stu);
};
ostream& operator << (ostream &out,  Cstu &stu)
{
	out << stu.age ;
	return out;
}
int main()
{
	Cstu stu;
	cout << stu;
	system("pause");
	return 0;
}

istream

#include<iostream>
using namespace std;

class Cstu
{
private:
	int a;
	float b;
public:
	Cstu()
	{
		a = 0;
		b = 0.0f;
	}
	void print()
		cout << a <<' ' <<  b;
	friend istream& operator >> (istream& in, Cstu &stu);
};
istream& operator >> (istream& in, Cstu &stu)
{
	in >> stu.a >> stu.b;   //输出
	if (in.fail())  //检测是否输入失败  
	 //可以写一个if判断    进到in.fail里,返回的是1
	{
//这里面主要的作用是将输错的数据赋一个初始值 
// 因为不赋值的话,下面还可能会有更多的错误
		stu.a = 0;
		stu.b = 0;
	}
	return in;
}
int main()
{
	Cstu stu;
	cin >> stu;
	stu.print();
	system("pause");
	return 0;
}

ostream的异同:
1.多了一个检测是否输入失败,目的是防止导致更多的错误
2.只能在类外重载,若在类内要写友元

赋值运算符重载
两种:(二元运算符)
1.‘=’
2.符合赋值运算符:+=,-=,/=,%=,<<=,^=,&=,|=等等。

上面说过
=、[]、()、->必须是成员

class Cstu
{
private:
	int a;
public:
	Cstu()
	{
		a = 12;
	}
	void print()
	{
		cout << a << endl;
	}
	void operator = (int b)
	{
		a = b;
	}
};
//主函数调用
	Cstu stu;
	stu = 13;
	stu.print();

“+=”赋值运算符的重载

//类内赋值
	int operator += (int d)
	{
		c += d;
		return c;
	}
//类外赋值运算符重载
Cstu& operator += (Cstu &stu1,int  &c)
{
	stu1.a += c;
	return stu1;
}
//主函数调用
	stu1.a  += 12;
	cout << stu1.a  << endl;  //外+=
	stu.print();  //内+=

下标运算符的重载
注意:
1.返回值引用
若不返回引用则在下面stu[1] = 14;左边仅是一个值不是变量,就会报错
可以通过指针取地址来解决
2.对象指向了元素后,可以修改值

#include<iostream>
using namespace std;
class Cstu
{
public:
		int a = 11;
		int b = 12;
		int c = 13;
	int&  operator [](int n)
	{
		switch (n)
		{
		case 0:
			return  a;
		case 1:
			return b;
		}
		return c;  //都没有返回c

	}
};
int main()
{
	Cstu stu;
	cout << stu[1] << endl;  //重载调用的形式
	stu[1] = 14;  //可以修改值
	cout << stu[1] << endl;
	system("pause");
	return 0;
}

利用指针:
void*operator[]() 通用类指针:
(1)即可以接受任何类型的指针,也可以可往任意类型去转,也能给任何类型的变量赋值(强转)
(2)无具体大小

	void*operator[](int n)
	{
		switch (n)
		{
		case 0:
			return &a;
		case 1:
			return &b;
		}
		return &c;
	}
	//主函数调用
	Cstu stu;
	cout << *(int*)stu[1] << endl;

递加递减运算符重载
原理和之前的都差不多
前置++:
类外:

class Cstu
{
public:
	int a;
	Cstu()
	{
		a = 12;
	}
};
int  operator ++(Cstu &stu)
{
	return (++stu.a );  //返回的是int型
}
//主函数调用
	Cstu stu;
	cout << ++stu.a << endl;

类内:

public:
	int a;
	Cstu()
	{
		a = 12;
	}
	int  operator ++() //没有参数
	{
		return (++a);
	}
};

前置- -同上
后置++:
类外:

class Cstu
{
public:
	int a;
	Cstu()
	{
		a = 12;
	}
};
int operator ++ (Cstu&stu, int n) //n是区别前置++的,仅是一个标记
{	
	int b = stu.a;  //b装的自加前的值
	stu.a++;
	return b;
}
//主函数调用
	Cstu stu;
	cout << stu++ << endl;  //调用  自加前的值
	cout << stu.a<< endl;  //自加后的值

后置- - 同上
重载类型转换
利用强转,是无法将对象转换为int型的

	Cstu stu;
	(int)stu;

这就用到重载类型转换
形式如下:

class Cstu
{
public:
	int a;
	double b;
	Cstu()
	{
		a = 12;
		b = 12.12;
	}
	operator int()  //对象转int就是这个形式  无返回值
	{
		return a;
	}
		operator int()  
	{
		return b;
	}
};
//主函数调用
	Cstu stu;
	cout << (int)stu <<(double)stu << endl;
	//也可以写成:stu(int)

注意:
1.没有返回类型,但要写返回值
2.没有参数
3.必须定义成类成员函数
4.不应对内容进行修改,定义成常函数

operator int()  const
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沐鑫本鑫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值