友元
类的主要特点之一是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。但是,有时候需要在类的外部访问类的私有成员,怎么办?
解决方法是使用友元函数,友元函数是一种特权函数,c++允许这个特权函数访问私有成员。
这一点从现实生活中也可以很好的理解∶
比如你的家,有客厅,有你的卧室,那么你的客厅是Public 的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的闺蜜好基友进去。
程序员可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元。
友元语法
friend关键字只出现在声明处
其他类、类成员函数、全局函数都可声明为友元
友元函数不是类的成员,不带 this指针
友元函数可访问对象任意成员属性,包括私有属性
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
class Building
{
//声明这个全局函数为Building类的友元
//这个函数不是成员函数
friend void GoodGay(Building &bd);
public:
Building()
{
keting = "客厅";
woshi = "卧室";
}
public:
string keting;
private:
string woshi;
};
void GoodGay(Building &bd)
{
cout << "好基友访问:" << bd.keting << endl;
cout << "好基友访问:" << bd.woshi << endl;
}
void test01()
{
Building my;
GoodGay(my);
}
int main()
{
test01();
system("pause");
return EXIT_SUCCESS;
}
友元类
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include<string>
class Building
{
//声明GoodF类为Building的友元类
friend class GoodF;
friend class GoodF2;
public:
Building()
{
keting = "客厅";
woshi = "卧室";
}
public:
string keting;
private:
string woshi;
};
class GoodF
{
public:
void func(Building &bd)
{
cout << "访问:" << bd.keting << endl;
cout << "访问:" << bd.woshi << endl;
}
};
//1、通过传入参数来访问类的私有成员
void test01()
{
Building bd;
GoodF f;
f.func(bd);
}
//2、通过类内指针来访问类的私有成员
class GoodF2
{
public:
GoodF2()
{
cout << "无参构造" << endl;
pbu = new Building;
}
void func()
{
cout << "访问:" << pbu->keting << endl;
cout << "访问:" << pbu->woshi << endl;
}
//拷贝构造
GoodF2(const GoodF2 &f2)
{
cout << "拷贝构造" << endl;
//1、申请空间
pbu = new Building;//new之后就有了数据
}
~GoodF2()
{
cout << "析构函数" << endl;
if (pbu!=NULL)
{
cout << "pbu" << endl;
delete pbu;
}
}
public:
Building *pbu;
};
void test02()
{
GoodF2 f;
f.func();
GoodF2 f2 = f;
}
int main()
{
//test01();
test02();
system("pause");
return EXIT_SUCCESS;
}
类的成员函数成为另一个友元函数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
//1、编译器只能看到类的声明不能看到类的结构
class Building;//声明类
class GoodGay
{
public:
void func(Building &bud);
};
class Building
{
//声明GoodGay类的成员函数func成为Building类的友元
friend void GoodGay::func(Building &bud);
public:
Building()
{
keting = "客厅";
woshi = "卧室";
}
public:
string keting;
private:
string woshi;
};
void GoodGay::func(Building &bud)
{
cout << "访问:" << bud.keting << endl;
cout << "访问:" << bud.woshi << endl;
}
void test()
{
Building bud;
GoodGay GF;
GF.func(bud);
}
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}
友元的注意事项
防止空指针调用成员函数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Maker
{
public:
Maker()
{
a = 20;
}
void printMaker()
{
if (this == NULL)
{
cout << "this==NULL" << endl;
return;
}
cout << this->a << endl;
}
private:
int a;
};
void test()
{
Maker *m = NULL;//this指针指向NULL,NULL里面没有a
m->printMaker();
}
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}