友元
写在前面
类的主要特点之一就是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。但是,有时候需要在类的外部访问类的私有数据成员,怎么办呢?
解决办法是使用友元函数,友元函数时一种特权函数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类的私有成员。
在友元类中我们应当注意:
- 友元关系不能被继承
- 友元关系是单向的
- 友元关系不具有传递性
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
来源:https://www.cnblogs.com/lijianming180/p/12014194.html