友元

穿精又带淫゛_ 提交于 2019-12-09 23:59:55

友元



写在前面

  类的主要特点之一就是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。但是,有时候需要在类的外部访问类的私有数据成员,怎么办呢?
  解决办法是使用友元函数,友元函数时一种特权函数c,C++允许这个特权函数访问私有成员。这一点我们可以用生活中的例子来看:   比如你的家有客厅,有卧室,客厅是public的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是,你可以允许你的好朋友进去。
  进程员可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元。

1.全局函数做友元函数

友元语法

  • friend关键字只出现在声明处
  • 其他类、类成员函数、全局函数都可以声明为友元
  • 友元函数不是类的成员,不带this指针
#include <iostream>
#include<string>
using namespace std;


class Home
{
public:
	friend void test(Home *home);
	Home()
	{
		this->bedroom = "卧室";
		this->sittingroom = "客厅";
	}
	string sittingroom;//客厅
private:
	string bedroom;//卧室

	
};


void test(Home *home)
{
	cout << "你的好友正在访问" << home->sittingroom << endl;
	cout << "你的好友正在访问" << home->bedroom << endl;
}
int main()
{
	Home *home=new Home;
	test(home);
}

输出结果如下:

从输出结果可以看出,当全局函数作为声明为友元函数之后,全局函数也可以访问类的私有成员。

2.整个类做友元类

#include <iostream>
#include<string>
using namespace std;


class Home
{
public:
	friend class Good_Friend;
	Home()
	{
		this->bedroom = "卧室";
		this->sittingroom = "客厅";
	}
	string sittingroom;//客厅
private:
	string bedroom;//卧室

	
};

class Good_Friend
{
public:
	Good_Friend(string name)
	{
		this->name = name;
	}
	void visit()
	{
		cout << "好友"<<this->name<<"正在拜访" << this->home.sittingroom << endl;
		cout << "好友"<<this->name<<"正在拜访" << this->home.bedroom << endl;
	}

private:
	Home home;
	string name;
};


void test()
{
	Good_Friend frend("Aoki");
	frend.visit();


}
int main()
{
	test();
}

  输出结果如下:


  将好友类声明为友元类之后,好友类的对象可以访问Home类的私有成员。
  在友元类中我们应当注意:
  1. 友元关系不能被继承
  2. 友元关系是单向的
  3. 友元关系不具有传递性

C++是纯面向对象的吗?
  如果一个类被声明为friend ,意味着它不是这个类的成员函数,却可以是修改这个类的私有成员,而且必须列在类的定义中,因此它是一个特权函数。C++不是完全的面向对象语言,而是一个混合产品。增加friend关键字只是用来解决一些实际问题,这也说明这种语言是不纯的。毕竟C++设计的目的是为了实用性,而不是追求理想的抽象。
-———《Think in C++》

</br>

#include <iostream>
#include<string>
using namespace std;

class Home;
class Good_Friend
{
public:
	Good_Friend(string name);
	void visit();
	void visit2();
private:
	Home *home;
	string name;
};

class Home
{
	friend void  Good_Friend::visit();
public:
	Home();
public:
	string sittingroom;
private:
	string bedroom;
};

Good_Friend::Good_Friend(string name)
{
	home = new Home;
	this->name = name;
}

void Good_Friend::visit()
{
	cout << "你的好友" << this->name << "正在访问" << this->home->sittingroom << endl;
	cout << "你的好友" << this->name << "正在访问" << this->home->bedroom << endl;
}

void Good_Friend::visit2()
{
	cout << "你的好友"<<this->name<<"正在访问" << this->home->sittingroom << endl;
	//cout << "你的好友" << this->name << "正在访问" << this->home->bedroom << endl;
}

Home::Home()
{
	this->sittingroom = "客厅";
	this->bedroom = "卧室";
}

void test()
{
	Good_Friend frien("Aoki");
	frien.visit();
	frien.visit2();
}

int main()
{
	test();
	return 0;
}

 &emsp当我们试图使用一个没有声明为Home类友元的成员函数去访问Home的私有成员时,编译器报错如下:


正确是输出结果如下:


  虽然我现在将visit()函数定义为Home类的友元,但是事情并没有这么简单地结束,因为当我第一次定义友元函数时,编译器莫名其妙地报错。那么,编译器报错的原因是什么呢?
  当我尝试着把成员函数的声明与定义分开的时候,编译器显示没有错误。这也就告诉我们,在声明成员函数的时候,将声明与定义分开放,编译器会更好地处理。







The End

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!