类的主要特点之一是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。但是,有时候需要在类的外部访问类的私有成员,怎么办?
解决方法是使用友元函数,友元函数是一种特权函数,c++允许这个特权函数访问私有成员。这一点从现实生活中也可以很好的理解:
比如你的家,有客厅,有你的卧室,那么你的客厅是Public的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的闺蜜好基友进去。
程序员可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元。
一、友元语法
- friend关键字只出现在声明处
- 其他类、类成员函数、全局函数都可声明为友元
- 友元函数不是类的成员,不带this指针
- 友元函数可访问对象任意成员属性,包括私有属性
class Building; //友元类 class MyFriend{ public: //友元成员函数 void LookAtBedRoom(Building& building); void PlayInBedRoom(Building& building); }; class Building{ //全局函数做友元函数 friend void CleanBedRoom(Building& building); #if 0 //成员函数做友元函数 friend void MyFriend::LookAtBedRoom(Building& building); friend void MyFriend::PlayInBedRoom(Building& building); #else //友元类 friend class MyFriend; #endif public: Building(); public: string mSittingRoom; private: string mBedroom; }; void MyFriend::LookAtBedRoom(Building& building){ cout << "我的朋友参观" << building.mBedroom << endl; } void MyFriend::PlayInBedRoom(Building& building){ cout << "我的朋友玩耍在" << building.mBedroom << endl; } //友元全局函数 void CleanBedRoom(Building& building){ cout << "友元全局函数访问" << building.mBedroom << endl; } Building::Building(){ this->mSittingRoom = "客厅"; this->mBedroom = "卧室"; } int main(){ Building building; MyFriend myfriend; CleanBedRoom(building); myfriend.LookAtBedRoom(building); myfriend.PlayInBedRoom(building); system("pause"); return EXIT_SUCCESS; } |
[友元类注意]
|
二、友元函数类型
1、全局函数做友元函数
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include <string>
using namespace std;
class Building
{
//让全局的好基友函数 变为我的好朋友 友元函数
friend void goodGay(Building * building);
public:
Building()
{
this->m_SittingRoom = "客厅";
this->m_BedRoom = "卧室";
}
//客厅 卧室
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom; //卧室
};
//全局函数 好基友
void goodGay( Building * building )
{
cout << "好基友正在访问 " << building->m_SittingRoom << endl;
cout << "好基友正在访问 " << building->m_BedRoom << endl;
}
//友元函数 目的访问类中的私有成员属性
void test01()
{
Building * building = new Building;
goodGay(building);
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
2、类做友元类
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include <string>
using namespace std;
class Building;
class goodGay
{
public:
goodGay();
void visit();
private:
Building * building;
};
class Building
{
//让好基友类 作为 Building的好朋友
friend class goodGay;
public:
Building();
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom; //卧室
};
goodGay::goodGay()
{
building = new Building;
}
void goodGay::visit()
{
cout << "好基友正在访问: " << this->building->m_SittingRoom << endl;
cout << "好基友正在访问: " << this->building->m_BedRoom << endl;
}
Building::Building()
{
this->m_SittingRoom = "客厅";
this->m_BedRoom = "卧室";
}
void test01()
{
goodGay gg;
gg.visit();
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
3、类成员函数做友元函数
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include <string>
//只让 visit可以作Building的好朋友 visit2 不可以访问私有属性
class Building;
class goodGay
{
public:
goodGay();
void visit();
void visit2();
private:
Building * building;
};
class Building
{
//让成员函数 visit作为友元函数
friend void goodGay::visit();
public:
Building();
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom; //卧室
};
goodGay::goodGay()
{
building = new Building;
}
void goodGay::visit()
{
cout << "好基友正在访问: " << this->building->m_SittingRoom << endl;
cout << "好基友正在访问: " << this->building->m_BedRoom << endl;
}
void goodGay::visit2()
{
cout << "好基友正在访问: " << this->building->m_SittingRoom << endl;
//cout << "好基友正在访问: " << this->building->m_BedRoom << endl;
}
Building::Building()
{
this->m_SittingRoom = "客厅";
this->m_BedRoom = "卧室";
}
void test01()
{
goodGay gg;
gg.visit();
gg.visit2();
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
思考: c++是纯面向对象的吗?
如果一个类被声明为friend,意味着它不是这个类的成员函数,却可以修改这个类的私有成员,而且必须列在类的定义中,因此他是一个特权函数。c++不是完全的面向对象语言,而只是一个混合产品。增加friend关键字只是用来解决一些实际问题,这也说明这种语言是不纯的。毕竟c++设计的目的是为了实用性,而不是追求理想的抽象。 --- Thinking in C++ |