我们知道c++的一个类中,可以自行访问成员变量和成员函数,此时不论什么访问权限,也都是可以访问的。
那对外呢?
对外界类,我们可以看一下下面这张表关于类与类之间访问权限进行的总结
(派生类是c++继承有关的知识点,外界函数对类内访问与表中“外部的类”访问权限情况是一致的。)
举个例子:
我们可以看见编译后有俩条明显的错误,说m_width与m_length是私有的.这里说明这外部函数是不能直接性的访问类内的私有成员的。
**表中我们也可以明显的看出外部是无法访问类中的私有成员的,那怎样使得外部可以访问到类中私有成员呢?**------**友元就可以达到这个目的,它可以让一个函数或者一个类访问另一个类中的私有成员。友元的关键字为 friend 。**
** 友元有三种实现:**
- 全局函数做友元
- 类做友元
- 成员函数做友元
(个人巧记:根据友元的关键字是friend,中文翻译是朋友的意思,我们可以理解为朋友之间的分享,从而促使函数或者另一个类可以访问自己)
**1.全局函数做友元**
在上面例子中,我要想让全局函数useShape(Shape& shape)可以访问到Shape类内成员而不会报错怎么做呢?**我们可以把这个全局函数当成这个类的好朋友,在这个类的开头声明一下----friend void useShape(Shape& shape);成为好朋友之后呢,就可以访问类中的私有成员了。**此处声明就和全局函数声明差不多,前面多加了个friend而已。
下面可以看一下完整的代码:
#include<bits/stdc++.h>
using namespace std;
//创建一个图形类.
class Shape{
//useShape全局函数是 Shape 好朋友,可以访问 Shape 中的私有成员.
friend void useShape(Shape& shape);
public:
Shape(int width,int length){
this->m_length = length;
this->m_width = width;
}
~Shape(){}
void printArear(){
cout<<m_width*m_length<<endl;
}
private:
int m_width;
int m_length;
};
//全局函数
void useShape(Shape& shape){
cout<<"Shape m_length is "<<shape.m_length<<endl;
cout<<"Shape m_width is "<<shape.m_width<<endl;
cout<<"Shape arear is ";
shape.printArear();
}
int main(){
Shape shape(4,5);
useShape(shape);
return 0;
}
2.类做友元
**类做友元和全局函数做友元操作其实差距不大,声明也是在类最上头声明就好,告诉自己这个类是自己的朋友,形式:friend class+类名;这样就可以访问私有成员了.**
直接看完整代码直观点:
#include<bits/stdc++.h>
using namespace std;
//创建一个图形类.
class Shape{
//ShapeGay类是 Shape 好朋友,可以访问 Shape 中的私有成员.
friend class ShapeGay;
public:
Shape(){
m_length = 5;
m_width = 4;
}
Shape(int width,int length){
this->m_length = length;
this->m_width = width;
}
~Shape(){}
void printArear(){
cout<<m_width*m_length<<endl;
}
private:
int m_width;
int m_length;
};
class ShapeGay{
public:
shapeGay(){
}
~ShapeGay(){
}
void visitShape(){
cout<<"Shape m_length is "<<shape.m_length<<endl;
cout<<"Shape m_width is "<<shape.m_width<<endl;
cout<<"Shape arear is ";
shape.printArear();
}
private:
Shape shape;
};
int main(){
ShapeGay gg;
gg.visitShape();
return 0;
}
3.成员函数做友元
**成员函数做友元我们可以在类内定义该成员函数,然后在类外实现这个函数(类外实现成员函数的格式:数据类型 类名::函数名()),记得进行注释,从而与其他函数进行区分,便于查看。这里需要把这个类的成员函数放类外实现,放在类内实现会报错。养成写在类外也是一个好的习惯,可以更好地维护代码。**
具体实现看代码:
#include<bits/stdc++.h>
using namespace std;
class Shape;//提前声明类,以免在其他类内使用报错
class ShapeGay{
private:
Shape* shape;
public:
ShapeGay();
~ShapeGay();
void visitShape(); //是Shape类的朋友,可以访问Shape类内的私有成员.
};
//创建一个图形类.
class Shape{
//ShapeGay类中visitShape()函数是 Shape 好朋友,可以访问 Shape 中的私有成员.
friend void ShapeGay::visitShape();
public:
Shape(){
m_length = 5;
m_width = 4;
}
Shape(int width,int length){
this->m_length = length;
this->m_width = width;
}
~Shape(){}
void printArear(){
cout<<m_width*m_length<<endl;
}
private:
int m_width;
int m_length;
};
ShapeGay::ShapeGay(){
shape = new Shape;
}
ShapeGay::~ShapeGay(){
delete shape;
}
void ShapeGay::visitShape(){
cout<<"Shape m_length is "<<shape->m_length<<endl;
cout<<"Shape m_width is "<<shape->m_width<<endl;
cout<<"Shape arear is ";
shape->printArear();
}
int main(){
ShapeGay gg;
gg.visitShape();
return 0;
}
(心里话对好朋友说啊)
版权归原作者 ·ᴥ· 所有, 如有侵权,请联系我们删除。