一般在封装类时会将成员属性设置为私有权限,将成员方法设置为公共权限。而有时需要向类外某些函数或类开放部分私有成员的访问权限,C++中引入友元以实现该功能,在类中使用关键字friend声明友元。
一、全局函数作为友元
class Person
{
//声明全局函数GoodSpy()是类Person的友元,向全局函数GoodSpy()开放私有成员属性car的访问权限
friend void GoodSpy(Person* person);
public:
Person(string nationality,string car)
{
this->nationality = nationality;
this->car = car;
cout << this->nationality << endl << this->car << endl << endl << endl;
}
public:
string nationality;
private:
string car;
};
void LowSpy(Person* person)
{
person->nationality = "USA";
cout << "您的操作系统已更换为: " << person->nationality << endl;
//报错,显示该成员属性为私有权限,不可被访问
//person->car = "Tesla";
//cout << "您的出厂设置已更换为: " << person->car << endl;
cout << "使用比亚迪为出厂设置,暂时无法更换" << endl << endl << endl;
}
void GoodSpy(Person* person)
{
person->nationality = "USA";
cout << "您的操作系统已更换为: " << person->nationality << endl;
//由于全局函数GoodSpy()为类Person的友元,所以类Person的私有成员也可被全局函数GoodSpy()访问
person->car = "Tesla";
cout << "您的出厂设置已更换为: " << person->car << endl << endl << endl;
}
void test()
{
Person Chou("中国", "比亚迪");
LowSpy(&Chou);
GoodSpy(&Chou);
}
int main()
{
test();
return 0;
}
二、类作为友元
//在类Person之前声明类GoodSpy,因为定义类Person时,其友元声明中涉及到类GoodSpy
class GoodSpy;
class Person
{
//声明类GoodSpy是类Person的友元,向类GoodSpy开放私有成员属性car的访问权限
friend class GoodSpy;
public:
Person(string nationality, string car);
public:
string nationality;
private:
string car;
};
//类LowSpy的定义放在类Person之后,因为类LowSpy中含有由类Person创建的对象成员
class LowSpy
{
public:
LowSpy();
void Action();
private:
Person* person;
};
//类GoodSpy的定义放在类Person之后,因为类GoodSpy中含有由类Person创建的对象成员
class GoodSpy
{
public:
GoodSpy();
void Action();
private:
Person* person;
};
Person::Person(string nationality, string car)
{
this->nationality = nationality;
this->car = car;
cout << this->nationality << endl << this->car << endl << endl << endl;
}
LowSpy::LowSpy()
{
this->person = new Person("中国", "比亚迪");
}
void LowSpy::Action()
{
cout << "For LowSpy:" << endl;
person->nationality = "USA";
cout << "您的操作系统已更换为: " << person->nationality << endl;
//报错,显示该成员属性为私有权限,不可被访问
//person->car = "Tesla";
//cout << "您的出厂设置已更换为: " << person->car << endl;
cout << "使用比亚迪为出厂设置,暂时无法更换" << endl << endl << endl;
}
GoodSpy::GoodSpy()
{
this->person = new Person("中国", "比亚迪");
}
void GoodSpy::Action()
{
cout << "For GoodSpy:" << endl;
person->nationality = "USA";
cout << "您的操作系统已更换为: " << person->nationality << endl;
//由于类GoodSpy为类Person的友元,所以类Person的私有成员也可被类GoodSpy访问
person->car = "Tesla";
cout << "您的出厂设置已更换为: " << person->car << endl << endl << endl;
}
void test()
{
LowSpy _250;
_250.Action();
GoodSpy _007;
_007.Action();
}
int main()
{
test();
return 0;
}
三、非静态成员函数作为友元
//与类作为友元时相比,非静态成员函数作为友元时要将类Spy的定义放在类Person的定义之前
//因为此时类Person声明友元时会涉及到类Spy中的GoodSpy(),若类Person的定义在前就需要在其定义之前声明GoodSpy()
//这在代码编写中无法实现,因为类的成员均不允许在类外进行声明
//在类Spy之前声明类Person,因为类Spy中含有由类Person创建的对象成员
class Person;
class Spy
{
public:
Spy();
void GoodSpy();
void LowSpy();
private:
Person* person;
};
//类Person的定义放在类Spy之后,因为定义类Person时,其友元声明中涉及到类Spy
class Person
{
//声明类Spy中的非静态成员函数GoodSpy()是类Person的友元,向非静态成员函数GoodSpy()开放私有成员属性car的访问权限
friend void Spy::GoodSpy();
public:
Person(string nationality, string car);
public:
string nationality;
private:
string car;
};
Spy::Spy()
{
this->person = new Person("中国", "比亚迪");
}
void Spy::LowSpy()
{
cout << "For LowSpy:" << endl;
person->nationality = "USA";
cout << "您的操作系统已更换为: " << person->nationality << endl;
//报错,显示该成员属性为私有权限,不可被访问
//person->car = "Tesla";
//cout << "您的出厂设置已更换为: " << person->car << endl;
cout << "使用比亚迪为出厂设置,暂时无法更换" << endl << endl << endl;
}
void Spy::GoodSpy()
{
cout << "For GoodSpy:" << endl;
person->nationality = "USA";
cout << "您的操作系统已更换为: " << person->nationality << endl;
//由于非静态成员函数GoodSpy()为类Person的友元,所以类Person的私有成员也可被非静态成员函数GoodSpy()访问
person->car = "Tesla";
cout << "您的出厂设置已更换为: " << person->car << endl << endl << endl;
}
Person::Person(string nationality, string car)
{
this->nationality = nationality;
this->car = car;
cout << this->nationality << endl << this->car << endl << endl << endl;
}
void test()
{
Spy Chou_01;
Chou_01.LowSpy();
Spy Chou_02;
Chou_01.GoodSpy();
}
int main()
{
test();
return 0;
}