六一的部落格


关关难过关关过,前路漫漫亦灿灿。



可以是类, 可以是函数, 还可以是其他类的成员函数

类的友元可以访问其protected和private成员

友元不受访问说明符的限制,一般在类的开头,第一个访问说明符之前给出. 或者在类的结尾

友元关系不能传递不能继承

友元关系的声明,不是对友元的名字进行声明

声明友元关系之前可以没有友元的名字的声明,建议有


将其他类的成员函数声明为友元

Screen的友元是类Window_mgr的成员函数:

  1. 定义Window_mgr类,声明clear函数,但是不能定义它:在clear使用Screen的成员之前必须先声明友元关系
  2. 定义Screen,包括与clear友元关系的声明
  3. 定义clear,此时clear可以使用Screen的成员
 1class Window_mgr
 2{
 3public:
 4    using ScreenIndex = std::vector<Screen>::size_type;
 5    void clear(ScreenIndex);
 6};
 7
 8class Screen
 9{
10    friend void Window_mgr::clear(ScreenIndex);
11};
12
13void Window_mgr::clear(ScreenIndex i)
14{
15    Screen &s = screens[i];
16    s.contents = string(s.height * s.width, ' ');
17}

在类内定义友元函数

友元关系声明的作用是影响访问权限,本身不具有普通声明的作用

可以在声明友元关系时给出友元函数的定义. 此时,认为友元函数未被声明. 在使用友元函数前, 仍需对友元函数声明先

 1struct X
 2{
 3    friend void f() { /* 允许在类的内部定义友元函数 */ }
 4    X() { f(); /* 错误:即使友元函数定义在类的内部,此时认为该函数未被声明,无法使用 */ }
 5    void g();
 6    void h();
 7};
 8
 9void X::g() { return f(); }    // 错误:认为f()未声明
10void f();                     // 声明定义在X中的函数
11void X::h() { return f(); }   // 正确

友元函数和重载

只有给出的友元关系声明对应的重载版本为友元

如果希望所有的重载版本都是友元,需要挨个声明


类的友元


可以是类, 可以是函数, 还可以是其他类的成员函数

类的友元可以访问其protected和private成员

友元不受访问说明符的限制,一般在类的开头,第一个访问说明符之前给出. 或者在类的结尾

友元关系不能传递不能继承

友元关系的声明,不是对友元的名字进行声明

声明友元关系之前可以没有友元的名字的声明,建议有


将其他类的成员函数声明为友元

Screen的友元是类Window_mgr的成员函数:

  1. 定义Window_mgr类,声明clear函数,但是不能定义它:在clear使用Screen的成员之前必须先声明友元关系
  2. 定义Screen,包括与clear友元关系的声明
  3. 定义clear,此时clear可以使用Screen的成员
 1class Window_mgr
 2{
 3public:
 4    using ScreenIndex = std::vector<Screen>::size_type;
 5    void clear(ScreenIndex);
 6};
 7
 8class Screen
 9{
10    friend void Window_mgr::clear(ScreenIndex);
11};
12
13void Window_mgr::clear(ScreenIndex i)
14{
15    Screen &s = screens[i];
16    s.contents = string(s.height * s.width, ' ');
17}

在类内定义友元函数

友元关系声明的作用是影响访问权限,本身不具有普通声明的作用

可以在声明友元关系时给出友元函数的定义. 此时,认为友元函数未被声明. 在使用友元函数前, 仍需对友元函数声明先

 1struct X
 2{
 3    friend void f() { /* 允许在类的内部定义友元函数 */ }
 4    X() { f(); /* 错误:即使友元函数定义在类的内部,此时认为该函数未被声明,无法使用 */ }
 5    void g();
 6    void h();
 7};
 8
 9void X::g() { return f(); }    // 错误:认为f()未声明
10void f();                     // 声明定义在X中的函数
11void X::h() { return f(); }   // 正确

友元函数和重载

只有给出的友元关系声明对应的重载版本为友元

如果希望所有的重载版本都是友元,需要挨个声明