友元函数重载和成员函数重载(具体的注释在代码中)
写在前面:
-
operator运算符符号(如:operator+)是重载运算符名字
-
重载运算符只能用友元函数或者成员函数中的一种
-
运算符重载就是重新定义运算符
-
左操作数为istream类的对象,右操作数为系统预定义的任意数据类型的变量,只能用友元函数重载
用成员函数重载
例题:重载运算符"+"
代码中,用到除重载之外的知识,也基本也都标出来了,二次记忆
注意,重载双目运算符时,有一个形参,重载单目运算符时,没有形参(在最后写了一个单双目运算符的表格)
#include <iostream>
using namespace std;
class Counter
{
int n;//别忘记成员函数名字和类名相同,这样定义对象的同时就可以调用成员函数了
public:
Counter(){n=0;};//这是默认构造函数,因为c3没有实参,需要调用默认构造函数,(没有默认构造函数会报错),c3的n就是0
Counter(int c)//这里定义的对象有实参就会被传给形参c,再通过这个函数把c的值给n,综上,最后对象的实参被传给了n
{
n=c;
}
Counter operator+(Counter &c)//向上面所说,成员函数名字和类名相同,因为自己第一次写的时候这里写错了(这个是用成员函数重载);
//另,operator是重载的一个标识;
//然后因为如果是显式调用,会写成c3=c1.operator+(c2),所以这里的函数小括号()里的是c2;
{
Counter temp;//打个比方,就像写a+b,需要一个记录这个值的
temp.n=n+c.n;//由上面的显式调用是c1调用的,所以这个单纯的n就是c1的n,然后后面那个c.n,由上一行代码的解析知道,这里的c就是c2,总结一下最终的结果导致从键盘输入的c3的实参和c2的实参相加值赋给了temp(注意这其中发生了多次传递)
return temp;
}
void print()//将d3的n输出
{
cout<<n<<endl;
}
};
int main()
{
int t,m;
cin>>t>>m;
Counter d1(t),d2(m),d3;//定义三个对象
d3=d1+d2;//d1调用重载,返回值temp,就给了d3;
d3.print();//注意这里d3的n的值是temp了
return 0;
}
写一下整个程序的实现
cin>>t>>m;——键入两个整数
Counter d1(t),d2(m),d3;——定义三个对象,其中两个对象有形参t,m,d3无参;定义的同时调用成员函数,d1,d2调用第二个成员函数,实参t,m分别传给c,再由c传给n;d3调用第一个默认构造函数
d3=d1+d2;——调用用成员函数实现的重载,最后d3的n的值即为返回值temp(注意在调用重载的时候,d3的n没有参与,只是最后因为”=“被赋值了)
d3.print();——d3的n此时的数值已经是返回值temp了,调用print输出
| p.s.:关于d3.print();d3是Counter类的对象,n是Counter的私有成员,也是对象所有的,同样Counter所有的成员函数,也是对象所有的 |
用友元函数重载
例题:重载前置运算符”++“
其实本质和构造函数重载相似,只是改变方式
需要注意的是,友元函数重载双目运算符时,参数有两个;重载单目运算符时,参数一个
#include<iostream>
using namespace std;
class point
{
int x,y;
public:
point(int,int);//当然也可以将此构造函数写在类内,这里写在类外了
friend void operator++(point&p);//友元函数声明,p可以省略
void print();
};
point::point(int a,int b)
{
x=a;
y=b;
}
void operator++(point &p)//友元函数可以直接调用类内所有
{
++p.x;
++p.y;
}
void point::print()
{
cout<<"("<<x<<","<<y<<")"<<endl;
}
int main()
{
int m,n;
cin>>m>>n;
point p(m,n);
++p;
p.print();
return 0;
}
该程序实现和上一个相似,代码中m和n即为两个数进行运算,需要几个设置几个
单目运算符和双目运算符
个人习惯常用排序
| 单目运算符 | 双目运算符 |
|---|---|
| 逻辑非运算符[!] | 算术运算符[+ - * / %] |
| 自增自减运算符[++ --] | 关系运算符[== != < > <= >=] |
| 指针运算符和取地址运算符[* &] | 赋值运算符[= += -= *=等等] |
| 按位取反运算符[~] | 逻辑运算符[&& ||] |
| 负号运算符[-] | 逗号运算符[,] |
| 长度运算符[sizeof] | 位运算符[<< >> | ^ &] |
最后
在进阶里写了重载++ --两种方法,用了this指针