一、 什么是友元
例如:你的生活中有一个特别好的朋友,你允许它进入你的房间(私有场所)也允许他进入客厅(相对公有场所),但是对于其他人你是不会允许他进入你的房间的,只允许他进入客厅。类对象也有这样类似的好朋友类,可以访问本类的私有成员,这个好朋友类就叫做这个类的友元,友元也可以是全局函数和别的类的成员函数,下面一一解答。
二、全局函数做友元
2.1创建建筑类
我们创建一个建筑类,这个建筑类里有私有成员卧室和公有成员客厅,和他的构造函数。
class Building
{
//friend void Godgay(Building& building);
public:
Building()
{
SittingRoom = "客厅";
BedRoom = "卧室";
}
public:
string SittingRoom;
private:
string BedRoom;
};
2.2创建好基友全局函数
然后我们再创建一个全局函数叫做好基友函数,我们让这个函数里面分别访问建筑类的卧室(私有)和客厅(公有)。我们会发现访问卧室时会报错,原因是因为卧室是建筑类私有成员,那么我们该如何访问这个私有成员呢,我们只需要让这个全局函数成为建筑类的友元即可,实现就是在建筑类的最上面加上friend和该全局函数的声明就可以了。
void Godgay(Building& building)
{
cout << "好基友正在访问:" << building.SittingRoom << endl;
cout << "好基友正在访问:" << building.BedRoom << endl;
}
2.3代码运行结果
运行结果如下
可以看到正常输出了好基友访问卧室。
2.4全局函数做友元全部代码
#include<iostream>
using namespace std;
class Building
{
friend void Godgay(Building& building);
public:
Building()
{
SittingRoom = "客厅";
BedRoom = "卧室";
}
public:
string SittingRoom;
private:
string BedRoom;
};
void Godgay(Building& building)
{
cout << "好基友正在访问:" << building.SittingRoom << endl;
cout << "好基友正在访问:" << building.BedRoom << endl;
}
void test01()
{
Building building;
Godgay(building);
}
int main() {
test01();
system("pause");
return 0;
}
三、类做友元
3.1创建建筑类
同样我们创建一个建筑类;里面有卧室(私有)和客厅(公有),(注意这里用到了成员函数的类外实现,即当我们创建类时在类内只写声明类外写实现。)
class Building
{
//不加下面这行代码时会报错,加了以后就可以实现友元,
//好基友类既可以正常访问建筑类的私有成员了
friend class GodGay;
public:
Building();
public:
string SittingRoom;
private:
string BedRoom;
};
Building::Building()
{
SittingRoom = "客厅";
BedRoom = "卧室";
}
3.2创建好基友类
然后我们创建一个好基友类,实现如下:(注意这里用到了成员函数的类外实现,即当我们创建类时在类内只写声明类外写实现。),在好基友类的构造函数中我们初始化了*building,(我们也可以不用指针直接创建一个建筑类对象,这里为了更好的练习我就使用了指针)
class GodGay
{
public:
void visit();
GodGay();
private:
Building *building;
};
GodGay::GodGay()
{
building=new Building;
//Building building;
}
void GodGay::visit()
{
cout << "好基友正在访问:" << building->SittingRoom << endl;
cout << "好基友正在访问:" << building->BedRoom << endl;
}
3.3运行结果
运行结果如下
可以看到正常输出了访问卧室。
3.4类做友元全部代码
#include<iostream>
using namespace std;
class Building;
class Building
{
friend class GodGay;
public:
Building();
public:
string SittingRoom;
private:
string BedRoom;
};
Building::Building()
{
SittingRoom = "客厅";
BedRoom = "卧室";
}
class GodGay
{
public:
void visit();
GodGay();
private:
Building *building;
};
GodGay::GodGay()
{
building=new Building;
//Building building;
}
void GodGay::visit()
{
cout << "好基友正在访问:" << building->SittingRoom << endl;
cout << "好基友正在访问:" << building->BedRoom << endl;
}
void test01()
{
GodGay gg;
gg.visit();
}
int main() {
test01();
system("pause");
return 0;
}
四、成员函数做友元
4.1创建建筑类
class Building
{
//成员函数做友元时我们要标明该成员函数是那个类的成员函数,
//这是和全局函数做友元的不同之处
friend void GoodGay::visit1();
public:
Building();
public:
string m_SittingRoom;
private:
string m_BedRoom;
};
Building::Building()
{
m_BedRoom = "卧室";
m_SittingRoom = "客厅";
}
4.2创建好基友成员函数
成员函数做友元和类做友元的区别就是类做友元,类中的所有成员函数都可以访问建筑类的私有成员,但成员函数做友元,只有该成员函数可以访问建筑类的私有成员,该类中其他不是友元的成员还有不可以访问建筑类的私有成员,为了显示出这一特性我们在下面的好基友类中创建两个成员函数一个做建筑类的友元,一个不做友元对比。下面是好基友类的实现(因为在堆区开辟了空间所以我们在析构函数中释放该空间,养成良好习惯)
class GoodGay
{
public:
GoodGay();
~GoodGay();
void visit1();//让他可以访问Building的私有成员
void visit2();//让他不可以访问Building的私有成员
private:
Building* building;
};
GoodGay::GoodGay()
{
building = new Building;
}
GoodGay::~GoodGay()
{
if(building!=NULL)
{
delete building;
building = NULL;
}
}
void GoodGay::visit1()
{
cout << "好基友正在访问:" << building->m_SittingRoom << endl;
cout << "好基友正在访问:" << building->m_BedRoom << endl;
}
void GoodGay::visit2()
{
cout << "好基友正在访问:" << building->m_SittingRoom << endl;
// cout << "好基友正在访问:" << building->m_BedRoom << endl;
}
4.3运行结果
我们发现做友元的visit1()可以正常访问建筑类的私有成员,但是visit2()不行,没有输出访问卧室。这就是成员函数做友元。
4.4成员函数做友元全部代码
#include<iostream>
using namespace std;
class Building;
class GoodGay
{
public:
GoodGay();
~GoodGay();
void visit1();//让他可以访问Building的私有成员
void visit2();//让他不可以访问Building的私有成员
private:
Building* building;
};
class Building
{
friend void GoodGay::visit1();
public:
Building();
public:
string m_SittingRoom;
private:
string m_BedRoom;
};
Building::Building()
{
m_BedRoom = "卧室";
m_SittingRoom = "客厅";
}
GoodGay::GoodGay()
{
building = new Building;
}
GoodGay::~GoodGay()
{
if(building!=NULL)
{
delete building;
building = NULL;
}
}
void GoodGay::visit1()
{
cout << "好基友正在访问:" << building->m_SittingRoom << endl;
cout << "好基友正在访问:" << building->m_BedRoom << endl;
}
void GoodGay::visit2()
{
cout << "好基友正在访问:" << building->m_SittingRoom << endl;
//不是友元,会报错
// cout << "好基友正在访问:" << building->m_BedRoom << endl;
}
void test01()
{
GoodGay gg;
gg.visit1();
gg.visit2();
}
int main() {
test01();
system("pause");
return 0;
}
五、总结
5.1三者做友元的不同
全局函数只需要加friend关键词和函数声明,但是成员函数做友元要表明成员函数的出处。
类做友元类中友元类的所有成员函数都可访问该类的私有成员,但成员函数做友元只有该成员函数可以访问该类的私有成员。
5.2三者做友元的相同之处
做友元都是要在类中加上friend关键字和声明
声明以上所有内容都是本人跟着黑马程序员学习之后做的总结,不会用于商业用途,只用作平时联系和分享,链接如下个人感觉链接讲的更加细致。
黑马程序员学C++