1.首先我们通过operator+加号运算符来了解成员函数与友元函数的区别。
首先我们来看一下operator+加号运算符,因为他的重载继可实现成员函数重载,也可以实现友元函数重载
。
1.加号运算符的成员函数
我们来看一下加号运算符的成员方法重载,我们主要看一下成员方法重载的结构,成员函数重载代码如下。
首先看一下整体代码,熟悉一下结构:
#include <bits/stdc++.h>
using namespace std;
struct Student{
string name;
int score;
//成员方法重载
Student operator+(const Student &student1){
this->score+=student1.score;
cout<<"输入的值"<<student1.score<<endl;
cout<<"相加之后的值"<<this->score<<endl;
return *this;
}
};
int main(){
Student student={"D",90};
Student student1={"A",100};
student.operator+(student1);
return 0;
}
复制代码
详细说明成员方法重载:
Student operator+(const Student &student1){
this->score+=student1.score; //用来实现相加
cout<<"输入的值"<<student1.score<<endl; //打印传入的值
cout<<"相加之后的值"<<this->score<<endl; //打印相加之后的值
return *this; //因为this是一个指针,需要以*this的形式输出值
}
复制代码
因为成员函数(也可以被成为Student中一个方法
)的话,我们是可以直接通过Student结构体来调用这个方法(只能因为他的名字比较特殊而已)如下代码:
Student a={"D",90};
Student b={"A",100};
a.operator+(b);
复制代码
我们可以看出直接就是==a来调用他的方法,然后传入需要相加的b来进行相加==。
又因为我们上方说了这个函数的名字比较特殊(所以肯定有他的特殊之处),我们直接可以通过下面方式来进行相加。
Student a={"D",90};
Student b={"A",100};
a+b;
复制代码
我们可以来看一下运行结果:
其实也可以实现多个Student来进行相加。
Student a={"D",90};
Student b={"A",100};
Student c={"C",100};
a+b+c;
复制代码
输出的结果:
2.加号运算符的友元函数
首先我先来说一下友元函数与成员函数的区别:
友元函数
1.是修饰的全局函数(也可以成为全局方法,所以他是没有this指针的
。
2.而且全局函数不能直接访问结构体或者类的私有属性,正因为全局函数不能直接访问私有属性,所以需要使用友元符来修饰全局函数实现让他可以访问类或者结构体的私有属性
。
3.其实结构体的friend友元符是可以不需要的,因为结构体默认为公共属性,而类默认为私有属性。所以因为结构体默认为公共属性,所以我们可以自己访问结构体的属性,所以就不要用友元符来修饰了是,下面我会举例说明一下
。
例:
(1).用友元符修饰的全局变量没有报错,而且可以达到我们想要的效果。
(2).不用友元符修饰的全局变量也没有报错,而且也可以输出。
成员函数是拥有this指针的,因为他可以看出结构体或者类的一个方法,所以他可以直接访问私有属性就不要用友元符来修饰。
整体代码:
#include <bits/stdc++.h>
using namespace std;
struct Student{
string name;
int score;
friend Student operator+(const Student &student1,const Student &student2);
};
Student operator+(const Student &student1,const Student &student2){
Student temp;
temp.score=student1.score+student2.score;
return temp;
}
int main(){
Student a={"D",90};
Student b={"A",100};
Student sum=operator+(a,b);
cout<<"相加之后的值"<<sum.score<<endl;
return 0;
}
复制代码
因为operator+是一个特殊重载方法,所以我们可以直接写成下方的相加形式。
Student a={"D",90};
Student b={"A",100};
Student sum=a+b;
cout<<"相加之后的值"<<sum.score<<endl;
return 0;
复制代码
所以我们可以得到加号运算符的成员函数和友元函数的重载都可以达到我们的效果
2.operator<<左移运算符不能重载成员函数,而只能重载为友元函数。
因为关于友元函数和成员函数区别,上面我有详细说明,这里我就不在做仔细的解释了。
1.左移运算符成员函数达不到我们的效果
首先我们想要的效果是:
cout<<Student<<endl;
因为原来的左移运算符是不能用来输出结构体Student的,所以我们需要重载来达到我们输出结构体的目的。
整体代码如下:
#include <bits/stdc++.h>
using namespace std;
struct Student{
string name;
int score;
void operator<<(const Student &student){
}
};
int main(){
Student a={"D",90};
Student b={"A",100};
a.operator<<(b);
return 0;
}
复制代码
成员函数:
void operator<<(const Student &student){
}
复制代码
如果我们调用这个方法的话,如下所示:
Student a={"D",90};
Student b={"A",100};
a.operator<<(b);
复制代码
==这样达不到我们想要的cout<<student<<endl的效果。因为他的左移运算符前不是我们需要的cout(因为cout是ostream类型)而且我们现在是a.opeartor是Student类型,所以达不到我们需要的效果。==
2.如果使用友元函数
整体代码:
#include <bits/stdc++.h>
using namespace std;
struct Student{
string name;
int score;
friend ostream& operator<<(ostream &os,const Student &student);
};
ostream& operator<<(ostream &os,const Student &student){
os<<"student的名字:"<<student.name<<" student的分数分:"<<student.score<<endl;
return os;
}
int main(){
Student a={"D",90};
operator<<(cout,a);
return 0;
}
复制代码
全局函数:
ostream& operator<<(ostream &os,const Student &student){
os<<"student的名字:"<<student.name<<" student的分数分:"<<student.score<<endl;
return os;
}
复制代码
其实这样也可以不需要使用friend友元符,因为struct默认为公共变量,全部函数可以直接访问
。
如何使用这个全局函数,如下方:
Student a={"D",90};
operator<<(cout,a);
复制代码
我们看一下效果:
因为opeartor<<是个左移运算符,所以他还有特殊的更简单的输出方式:
Student a={"D",90};
cout<<a<<endl;
复制代码
也可以达到我们所需要的效果: