给出以下代码:
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
的朋友可能是糟糕的设计。
我在哪里错了?什么是正确的方法?我自欺欺人了吗?
答案 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的原则,只有类的公共成员函数可以在另一个中声明为朋友,否则后者会依赖于前者的私有实现。