重载运算符
您可以重定义或重载大部分 C++ 内置的运算符。这样,您就能使用自定义类型的运算符。
重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。
与其他函数一样,重载运算符有一个返回类型和一个参数列表。
不能重载的运算符
写法 | 解释 |
---|---|
. | 成员访问运算符 |
., -> | 成员指针访问运算符 |
:: | 域运算符 |
sizeof | 长度运算符 |
? | 条件运算符(三目运算符) |
# | 预处理符号 |
单目/双目/三目运算符
- 单目就是这个运算符只对一个变量进行操作
代表符号:!(逻辑非) ~(按位取反)++(自增)–(自减)
举例:int a=1;a++;(第二句“a++”则只对a一个变量进行了操作) - 双目就是这个运算符对两个变量进行操作
举例:int a=1,b=2,c;c=a+b;(第二句“c=a+b”则是对a,b两个变量进行了操作) - 三目就是这个运算符对三个变量进行操作
代表符号: ?:(条件运算符)
重载运算符的方式
重载运算符的方式有哪几种?
(1)令运算符重载函数作为类的成员函数
(2)令运算符重载函数作为类的友元函数
成员函数重载+号代码
#include <iostream>
using namespace std;
class player{
public:
int keyBoard;
int mouse;
player(int k, int m):keyBoard(k),mouse(m){ };
player(){ };
player operator+(const player &a){
player temp;
temp.keyBoard = this->keyBoard + a.keyBoard;
temp.mouse = this->mouse + a.mouse;
return temp;
}
};
int main(){
player t0tott(1,2);
player r0rott(2,3);
player ans = t0tott+r0rott;
cout<<"player ans = player(1,2) + player(2,3);"<<endl;
cout<<ans.keyBoard<<' '<<ans.mouse<<endl;
return 0;
}
输出:
(base) Cpp ./OverLoadOperator
player ans = player(1,2) + player(2,3);
3 5
友元函数重载+运算符
#include <iostream>
using namespace std;
class player{
public:
int keyBoard;
int mouse;
player(int k, int m):keyBoard(k),mouse(m){ };
player(){ };
player operator+(const player &p);
friend player operator*(const int &nums, const player &p);
};
player player::operator+(const player &p){
player temp;
temp.keyBoard = this->keyBoard + p.keyBoard;
temp.mouse = this->mouse + p.mouse;
return temp;
}
player operator*(const int &nums, const player &p){
player temp;
temp.keyBoard = nums * p.keyBoard;
temp.mouse = nums * p.mouse;
return temp;
}
int main(){
player t0tott(1,2);
player r0rott(2,3);
player ans = t0tott+r0rott;
cout<<"player ans = player(1,2) + player(2,3);"<<endl;
cout<<ans.keyBoard<<' '<<ans.mouse<<endl;
cout<<"player ans = 3 * player(1,2)"<<endl;
ans = 3*t0tott;
cout<<ans.keyBoard<<' '<<ans.mouse<<endl;
return 0;
}
输出
(base) Cpp ./OverLoadOperatorFriend
player ans = player(1,2) + player(2,3);
3 5
player ans = 3 * player(1,2)
3 6
友元函数
引入友元函数的原因
类具有封装、继承、多态、信息隐藏的特性,只有类的成员函数才可以访问类的私有成员,非成员函数只能访问类的公有成员。
**为了使类的非成员函数访问类的成员,唯一的做法就是将成员定义为public,但这样做会破坏信息隐藏的特性。**基于以上原因,引入友元函数解决。
友元不是类的成员,不受类的声明区域public、private和protected的影响。
申明 定义方式
必须在类的说明中说明友元函数,说明时以关键字friend开头,后跟友元函数的函数原型,友元函数的说明可以出现在类的任何地方,包括private和public部分。
友元函数不是类的成员函数,所以友元函数的实现与普通函数一样。在实现时不用“::”指示属于哪个类,只有成员函数才使用“::”作用域符号。
- 友元函数不能直接访问类的成员,只能访问对象成员。
- 友元函数可以访问对象的私有成员,但普通函数不行。
- 调用友元函数时,在实际参数中需要指出要访问的对象。
- 类与类之间的友元关系不能被继承。(友元不属于类的成员函数)
- 友元的正确使用能提高程序的运行效率,但同时也破坏了类的封装性和数据的隐藏性,导致程序可维护性变差。
- 一个类的成员函数也可以作为另一个类的友元,但必须先定义这个类。
封装
什么是封装?
封装: 封装可以隐藏实现细节,使得代码模块化
封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。
在面向对象编程上可理解为:把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。