友元类有以下两个特点:
(1)如果B声明成A的友元类,那么B可以访问A的protected、private成员。但是A不能访问B的protected、private成员。
(2)如果C继承B,C不能访问A的protected、private数据成员和函数,只能访问A的public成员。但是可以通过B的公共接口获取到A的protected、private信息。
现在按照以下代码深入分析:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
class Father;
class Mother;
class Father
{
public:
Father()
{
m_nAge = 1;
m_nWeChat = 1;
m_nSalary = 1;
}
~Father()
{
m_nAge = 0;
m_nWeChat = 0;
m_nSalary = 0;
}
friend class Mother; //Mother是Father的友元类
public:
void PrintfAge()
{
printf("Father's age is 30.\n");
}
//void FatherGetMotherInfo(Mother &tMother)
//{
// printf("Father get mother info\n");
// //只能访问Mother的public成员
// printf("Mother public m_nSex : [%d]\n", tMother.m_nSex);
// printf("------------------\n\n");
//}
private:
void PrintfSalay()
{
printf("Father's salary is secret.\n");
}
public:
int m_nAge; //年龄
protected:
int m_nWeChat; //微信
private:
int m_nSalary; //工资
};
class Mother
{
public:
Mother()
{
m_nSex = 2;
m_nQQ = 2;
m_nPayCard = 2;
}
~Mother()
{
m_nSex = 0;
m_nQQ = 0;
m_nPayCard = 0;
}
public:
void MotherGetFatherInfo(Father &tFather)
{
printf("Mother get father info\n");
printf("------------------\n");
//Mother是Father的友元类,可以访问Father的public、protected、private成员和函数
printf("Father public m_nAge : [%d]\n", tFather.m_nAge);
printf("Father protected m_nWeChat : [%d]\n", tFather.m_nWeChat);
printf("Father private m_nSalary : [%d]\n", tFather.m_nSalary);
tFather.PrintfAge();
tFather.PrintfSalay();
printf("------------------\n\n");
}
public:
int m_nSex; //性别
protected:
int m_nQQ; //QQ
private:
int m_nPayCard; //工资卡
};
class Son : public Mother
{
public:
Son()
{
m_nGirlFriend = 3;
}
~Son()
{
m_nGirlFriend = 0;
}
public:
void SunGetFatherInfo(Father &tFather)
{
printf("Son get father info\n");
printf("------------------\n");
printf("Father public m_nAge : [%d]\n", tFather.m_nAge);
//友元关系不能被继承,所以没法访问Father的m_nWeChat、m_nSalary、PrintfSalay等protected和private成员、函数
//printf("Father protected m_nWeChat : [%d]\n", tFather.m_nWeChat);
//printf("Father private m_nSalary : [%d]\n", tFather.m_nSalary);
tFather.PrintfAge();
//tFather.PrintfSalay();
printf("------------------\n\n");
}
void SunGetFatherInfoByMother(Father& tFather)
{
printf("Son get father info by mother\n");
MotherGetFatherInfo(tFather);//虽然自己获取不到Father私有信息,可以通过Mother获取Father私有信息
}
private:
int m_nGirlFriend;
};
int main()
{
Father tFather;
Mother tMother;
Son tSon;
//tFather.FatherGetMotherInfo(tMother);
tMother.MotherGetFatherInfo(tFather);
tSon.SunGetFatherInfo(tFather);
tSon.SunGetFatherInfoByMother(tFather);
return 0;
}
上述代码中,Mother是Father的友元函数,那么Father在Mother这没有任何隐私可言,即Mother可以访问Father的public年龄m_nAge、protected微信m_nWeChat、private工资m_nSalary,而Father只能访问Mother的public性别m_nSex。Son继承Mother,注意的是不能将友元关系继承下来,试想本身友元已经破坏了类的封装特性了,假如友元关系能继承下来,类与类的关系就非常乱了,难以维护这么错综复杂的关系,所以Son只能访问Father的public年龄m_nAge。但是Son可以通过Mother的public函数MotherGetFatherInfo获取到Father的私人信息。
|