如何给友元类设置访问权限?
友元类无限制地访问所在类的所有元素
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class Student;
class Person
{
friend class Student; // 显然友元类可以访问Person类中的所有成员(public,private,protected)
private:
int mark;
string name;
public:
Person() = default;
Person(const int& mark, const string& name)
{
this->mark = mark;
this->name = name;
}
Person& operator = (Person&& obj)
{
this->mark = obj.mark;
this->name = obj.name;
return *this;
}
};
class Student
{
private:
Person obj;
public:
Student() = default;
Student(const int& mark, const string& name) // const引用允许接受右值
{
obj = { mark,name }; // 先生成匿名对象,然后调用重载赋值运算符赋值给obj
}
void ShowInf()
{
cout << obj.name << "的成绩是" << obj.mark << endl;
}
};
int main()
{
Student obj(99, "张三");
obj.ShowInf();
}
上面这个例子表明,如果我们不对友元类加以限制,友元类会彻底地破坏封装,使得类的封装形同虚设,完全地自由地访问所在类的所有成员。
我们知道:友元函数的访问权限只限于友元声明所在的类的作用域,即如上述例子所示,Student友元类的作用范围仅限于Person类域之内。
我们想:如何才可以对friend类的访问权限加以限制呢?
友元类的访问权限设置
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class Student;
class Person
{
//friend class Student; // 显然友元类可以访问Person类中的所有成员(public,private,protected)
private:
int mark;
string name;
char age;
string schoolname;
public:
class subclass
{
friend class Student;
private:
int mark;
string name;
public:
subclass() = default;
subclass(const int& mark, const string& name)
{
this->mark = mark;
this->name = name;
}
subclass& operator = (subclass&& obj)
{
this->mark = obj.mark;
this->name = obj.name;
return *this;
}
void ShowInf()
{
cout << this->name << "的成绩是" << this->mark << endl;
}
} subobj;
public:
Person() = default;
Person(const int& mark,const string& name,const char& age,const string& schoolname)
{
this->mark = mark;
this->name = name;
subobj = { mark,name }; // 匿名对象的赋值操作一定要使用右值引用
this->age = age;
this->schoolname = schoolname;
}
Person& operator = (Person&& obj)
{
this->mark = obj.mark;
this->name = obj.name;
this->age = obj.age;
this->subobj = move(obj.subobj);
this->schoolname = obj.schoolname;
return *this;
}
};
class Student
{
private:
Person obj;
public:
Student() = default;
Student(const int& mark, const string& name, const char& age, const string& schoolname) // const引用允许接受右值
{
obj = { mark,name,age,schoolname }; // 先生成匿名对象,然后调用重载赋值运算符赋值给obj
}
void ShowInf()
{
//cout << obj.name << "的成绩是" << obj.mark << endl;
obj.subobj.ShowInf();
}
};
int main()
{
Student obj(99, "张三", 'f', "水城中学");;
obj.ShowInf();
}
如上述例子所示,friend类访问权限限制方法如下:
为什么要声明subclass子类数据成员为共有权限类型,而非私有权限类型?
Student类不是Person类的友元函数没办法破除封装,Student类是Person.subclass子类成员的友元类,可以破除Person.subclass子类成员的封装,因此声明subclass子类成员为公有属性的数据成员实际上是人为的向外提供了数据访问的接口。Student类中以及任何定义了Person类对象的地方都可以随心所欲的访问subclass子类,但是只有Student类可以破除subclass类成员的封装访问subclass中的所有数据。