3

给定以下代码:

class Screen;

class WindowMgr
{
    WindowMgr& relocateScreen( int r, int c, Screen& s);
};

class Screen
{
    friend WindowMgr& WindowMgr::relocateScreen( int r, int c, Screen& s);
    // ^ cannot access private member declared in class 'WindowMgr'

    int m_nR,
        m_nC;
};

WindowMgr& WindowMgr::relocateScreen( int r, int c, Screen& s)
{
    s.m_nR = r;
    s.m_nC = c;
    return *this;
}

为什么Screen类不能声明WindowMgr::relocateScreen成员函数为友元?Screen不想使用另一个类的这个私有成员函数,而只是希望该函数能够访问它自己的私有成员。

relocateScreen如果仅打算在WindowMgr类中使用,则将函数公开可能是糟糕的设计。同样,如果不打算在任何其他情况下访问私有成员,那么结交Screenof 的朋友可能是糟糕的设计。WindowMgrWindowMgr

我在哪里错了?什么是正确的方法?我是在自欺欺人吗?

4

4 回答 4

1

朋友声明不起作用,因为WindowMgr::relocateScreen()它是私有的WindowMgr

C++ 标准 11.4-7:

“由友元声明指定的名称应可在包含友元声明的类范围内访问……”

就个人而言,我会创建relocateScreen()一个私有成员函数Screen并创建WindowMgr一个friendof Screen。这样,WindowMgr可以直接调用relocateScreen()Screen而不必触及Screen.

于 2010-07-21T20:08:46.690 回答
0

WindowMgr 必须将 Screen 声明为朋友。您可以使用前向声明。

于 2010-07-21T20:05:25.820 回答
0

为什么不将 WindowMgr::relocateScreen 分解到不同的类中,比如带有 1 relocateScreen 函数的 WindowMgrFoo。Delcare WindowMgrFoo 是 Screen in Screen 的朋友,让 WindowMgr 从 WindowMgrFoo 私下继承?或者只是让 WindowMgr 具有对 WindowMgrFoo 的引用,但是如果将其公开,则需要更改用户调用它的方式。

于 2010-07-21T20:12:20.880 回答
0

In Silico - 引用标准的好方法。睡在上面后,我现在看到了理由:

通过WindowMgr::relocateScreen将其参数列表声明为 中的朋友ScreenScreen该类变得依赖于该类的私有实现WindowMgr。这违反了封装/信息隐藏。

为了不违反 OOD 的原则,只有类的公共成员函数可以声明为另一个类的朋友,否则后者将依赖于前者的私有实现。

于 2010-07-22T11:06:47.843 回答