C++-类:友元(在类的外部访问类的私有成员)【①全局函数做友元函数;②类做友元类;③类成员函数做友元函数】

类的主要特点之一是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。但是,有时候需要在类的外部访问类的私有成员,怎么办?

解决方法是使用友元函数,友元函数是一种特权函数,c++允许这个特权函数访问私有成员。这一点从现实生活中也可以很好的理解:

比如你的家,有客厅,有你的卧室,那么你的客厅是Public的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的闺蜜好基友进去。

程序员可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元。

一、友元语法

  1. friend关键字只出现在声明处
  2. 其他类、类成员函数、全局函数都可声明为友元
  3. 友元函数不是类的成员,不带this指针
  4. 友元函数可访问对象任意成员属性,包括私有属性

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. 友元关系不能被继承。
  2. 友元关系是单向的,类A是类B的朋友,但类B不一定是类A的朋友。
  3. 友元关系不具有传递性。类B是类A的朋友,类C是类B的朋友,但类C不一定是类A的朋友。

二、友元函数类型

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++

  • 21
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值