为什么我不能在一个属于另一个类的私有成员的类中声明一个朋友?

时间:2010-07-21 19:57:41

标签: c++ private friend member-functions

给出以下代码:

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类中使用。同样,如果Screen的朋友在任何其他情况下无意访问WindowMgr的私人成员,那么WindowMgr的朋友可能是糟糕的设计。

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

4 个答案:

答案 0 :(得分:1)

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

C ++标准11.4-7:

  

“朋友提名的名字   声明应在   包含该类的类的范围   朋友宣言......“

就个人而言,我会将relocateScreen()设为Screen的私人会员功能,并使WindowMgr成为friend Screen。这样,WindowMgr只需拨打relocateScreen()上的Screen即可,无需触及Screen的任何数据成员。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

在Silico - 很好的引用标准。睡了之后我现在看到了理由:

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

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