C++_基础_运算符重载

时间:2024-06-23 09:06:20

内容:

(1)输入输出运算符重载
(2)友元类和友元函数
(3)双目运算符重载
(4)单目运算符重载
(5)不能被重载的运算符
(6)只能定义为成员形式的运算符

1.输入输出运算符重载
如:
int num = 10;
cout << num << endl; //10
char c = 'A';
cout << c << endl; //'A'
double d = 3.14;
cout << d << endl; //3.14
Student s;
cout << s << endl;

解析为:
cout.operator<<(num);
cout.operator<<(c);
cout.operator<<(d);
cout.operator<<(s);

再次解析:
cout.operator<<(int);
cout.operator<<(char);
cout.operator<<(double);
cout.operator<<(Student);

/usr/include/c++/4.6/ostream文件
ostream是一个类类型,是cout的数据类型

再次解析:
operator<<(cout,s);
operator<<(ostream,Student);

注意:
cin是istream类型的对象

练习:
自定义一个分数类,属性有:分子和分母,提供一个有参的构造函数,要求支持输入输出运算符重载
如:
2/3 分母不可以为0

2.友元类和友元函数
使用friend关键字修饰的类和函数

(1)友元不是成员,只是为了声明它可以访问我的私有部分而已,被声明的友元可以访问类中的任何成员
(2)友元声明可以出现在类的公有、私有、保护任何一个部分,效果都是一样的,不受访控属性的限制,一般放在类的尾部

3.双目运算符重载
格式:
L/*左操作数*/ #/*运算符*/ R(右操作数)
=> L.operator#(R); 成员形式
=> operator#(L,R); 非成员形式

如:
s + s2;
=> s.operator+(s2);
=> operator+(s,s2);

建议:
尽量使用成员形式的重载函数

练习:
在分数类中,编写支持 + - += -=运算符重载
1/2 + 1/3 = 3/6 + 2/6 = 5/6

4.单目运算符重载
4.1 格式:
O/*操作数*/ #/*操作符*/
=>O.operator#(); 成员形式
=>operator#(O); 非成员形式

练习:
自定义复数类,要求支持输出运算符重载即可

4.2 自增减运算符的重载
(1)前缀自增减运算符
a.表达式的值是增减以后的值
b.运算函数返回的是操作数的引用
c.成员形式的运算符函数没有参数,友元形式的运算符函数只有一个参数 - 操作数
d.可以连用

(2)后缀自增减运算符
a.表达式的值是增减以前的值
b.运算函数返回的增减以前的副本
c.成员形式运算符函数有一个int类型的哑元参数;友元形式运算符函数有两个参数,第一个是操作数,第二个是int类型的哑元
d.不可以连用

练习:
自定义分数类,要求有参的构造函数,支持输出运算符重载,负号重载,以及前后缀++运算符重载

4.3 类型转换运算符函数
在源类型中定义如下形式的函数:
operator 目标类型(void)
{
构造一个目标类型的对象,返回
}

功能:
将源类型的对象转换为目标类型的对象

注意:
如果在源类型中提供类型转换运算符函数的同时,在目标类型中定义了类型转换的构造函数,则对于隐式类型转换则优先选择类型转换运算符函数,而对于显式类型转换,则优先选择类型转换的构造函数

建议:
建议不要提供两个,优先选择构造函数的方法(explicit)

5.不能被用户重载的运算符
:: - 作用域限定符
. - 成员访问操作符
.* - 成员指针解引用
?: - 三目运算符
sizeof - 计算类型的大小
typeid - 获取数据类型的名称

注意:
(1)操作符的操作数中没有类类型的操作数,不能重载
(2)不能通过重载运算符去发明新的操作符
如: * **

作业:
实现一个整型的数组类IntArray,通过构造函数来指定数组的容量,注意在析构函数释放资源,提供的成员函数有:
push() 在数组的尾部插入一个元素
pop() 在数组的尾部弹出一个元素
get() 根据下标获取一个元素的值
set() 根据下标设置一个元素的值
print() 打印数组中的所有元素