从C学C++(8)——友元
从C学C++(8)-友元
若无特殊说明,本博客所执行的C++标准均为C++11.
友元机制
-
友元是一种允许非类成员函数访问类的非公有成员的一种机制。
友元个人认为是填上了 作用域为整个文件但可以不受限制的访问某个类的成员(私有/保护)的函数/类 这样的一个空白。
-
可以把一个函数指定为类的友元(友元函数),也可以把整个类指定为另一个类的友元(友元类)。
友元函数
定义
-
友元函数在类作用域外定义,但它需要在类体中进行说明。
-
为了与该类的成员函数加以区别,定义的方式是在类中用关键字
friend
说明该函数,格式如下:class A {friend void func(int a); //友元函数在类中的说明,函数体可以定义在这个类里,也可以定义在外部,没有影响 }void func(int a); //定义在外部时,不需要加上域访问的限制,因为他作用域是整个文件(不论定义在外部还是类里)。
友元的作用在于提高程序的运行效率(不需要访问某个类的私有成员时为这些成员单独留下公有的访问接口函数)。
注意事项
- 友元函数不是类的成员函数,在函数体中访问对象的成员,必须用对象名加运算符“."加对象成员名 (注意和成员函数访问自身成员还是不一样的,因为没有隐含的
this
指针,可以说友元只是授予了访问权限而已)。但友元函数可以访问类中的所有成员(公有的、私有的、保护的),一般函数只能访问类中的公有成员。 - 友元函数不受类中的访问权限关键字限制,可以把它放在类的公有、私有、保护部分,但结果一样。
- 某类的友元函数的作用域并非该类作用域。如果该友元函数是另一类的成员函数(就是下面要说到的友元类),则其作用域为另一类的作用域,否则与一般函数相同。
- 友元函数破坏了面向对象程序设计类的封装性,所以友元函数如不是必须使用,则尽可能少用。或者用其他手段保证封装性。
友元类
定义
-
如果某类B的成员函数会频繁的存取另一个类A的数据成员,而A的数据成员的
private
/protectd
限制造成B存取的麻烦,B只能通过A的Public的成员函数进行间接存取。把B做成A类的友元类,即A类向B类开放其private
/protectd
内容,让B直接存取, 可以提高程序的运行效率。 -
友元类:一个类可以作另一个类的友元,需要在这个类中声明另一个类是友元类如下:
class A {friend class B; // B是A的友元,也就是说,B有权限访问A的所有成员(这是在A里声明B是友元)... }class B {void func(int a); // B的所有成员函数都是友元函数,都有权限访问A的所有成员 }
-
友元类的所有成员函数都是另一个类的友元函数。
注意事项
-
友元关系是单向的。
像上面在A中声明B是A的友元,B有权访问A中所有成员。但如果B中没有声明A是友元类的话,A是没有权限访问B中所有成员的。(就像现实中,你把别人当friend, 别人不一定把你当friend一样,好现实的friend😭)
-
友元关系不能传递。
假设A中声明B是友元,向上面的例子一样,B有权访问A中所有成员。再在B中声明一个类C是B的友元,C有权访问B中所有成员,但C没有权限访问A中的所有成员。(就像现实中,你是我的朋友,但你的朋友有可能我也不认识,所以不可以访问我😂)
-
友元关系不能继承。
像上面说的一样,A中声明B是友元,B有一个子类D,或者说D继承自B,但D也没有权限访问A中的所有成员。(和现实中一样,你是我朋友,你的儿子不一定是我朋友,所以不可以访问我🤣)