C++——成员函数和友元

  • Post author:
  • Post category:其他


既然友元具有访问权限,那么当把一个成员函数声明成友元的时候,我们必须要指明该成员函数属于哪个类:

class Screen {
    // Window_mgr::clear必须在Screen类之前被声明
    friend void Window_mgr::clear(ScreenIndex);
    // Screen类的剩余部分
};

想要令某个成员函数作为友元,我们必须仔细组织结构。首先定义类,其中声明clear函数,但不能定义。在clear使用Screen的成员之前必须先声明Screen。接下来定义Screen,包括对clear的友元声明。最后定义clear,此时它可以使用Screen的成员。

重载函数在声明成友元的过程中,需要对函数中的每一个分别进行声明:

extern std::ostream& storeOn(std::ostream &, Screen &);
extern BitMap& storeOn (BitMap &, Screen &);
class Screen {
    // storeOn的ostream版本能访问Screen对象的私有部分
    friend std::ostream& storeOn(std::ostream &, Screen &);    
};

未被声明之前,友元的类的成员无法调用该友元函数:

struct X {
    friend void f() { /* 友元函数可以定义在类的内部*/ }
    x() { f(); }        // 错误:f尚未被声明
    void g();
    void h();    
 };
void X::g() { return f(); }//错误:f未被声明
void f();                  //声明定义在X中的函数
void X::h() { return f(); }//正确:f已被声明

类的作用域:

每个类具有自己的作用域。在作用域之外,普通的数据和函数成员只能由对象、引用或者指针使用成员访问运算符来访问。对于类类型的成员则使用作用域运算符来访问。不论哪种情况,运算符之后的名字必须是对应类的成员:

Screen::pos ht = 24, wd = 80;    //使用Screen定义的pos类型
Screen scr(ht, wd, ' ');
Screen *p = &scr;
char c = scr.get();              //访问scr对象的get成员
c = p->get();                    //访问p所指对象的get成员

void Window_mgr::clear(ScreenIndex i)
{
    Screen &s = screens[i];
    s.contents = string(s.height * s.width, ' ');
}

函数的返回类型通常出现在函数名之前。因此当成员函数定义在类的外部时,返回类型中使用的名字都位于类的作用域之外。我们可以向Window_mgr类中添加一个新的名为addScreen的函数,它负责向显示器添加一个新的屏幕。这个成员的返回类型将是ScreenIndex, 用户可以通过它定义到指定Screen:

class Window_mgr {
public:
    //向窗口添加一个Screen, 返回它的编号
    ScreenIndex addScreen(const Screen&);
    // 其他成员与之前的版本一样
};
//首先处理返回类型,之后我们才进入Window_mgr的作用域
Window_mgr::ScreenIndex
Window_mgr::addScreen(const Screen &s)
{
    screens.push_back(s);
    return screens.size() - 1;
}



版权声明:本文为MDeleter原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。