[英]Why can't I declare a friend in one class that is a private member of another class?
Given the following code: 给出以下代码:
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;
}
Why can the Screen
class not declare the WindowMgr::relocateScreen
member function as a friend? 为什么
Screen
类不能将WindowMgr::relocateScreen
成员函数声明为朋友? Screen
is not wanting to use this private member-function of another class, but simply wants that function to be able access its own private members. Screen
不想使用另一个类的私有成员函数,而只是希望该函数能够访问自己的私有成员。
Making the relocateScreen
function public might be bad design if it's intented only for use within the WindowMgr
class. 使得
relocateScreen
,如果是只用在内部使用功能的公共可能是糟糕的设计WindowMgr
类。 Equally, making Screen
a friend of WindowMgr
might be bad design if it is not intented to access private members of WindowMgr
in any other case. 同样,如果
WindowMgr
在任何其他情况下访问WindowMgr
私有成员, WindowMgr
使Screen
成为WindowMgr
的朋友可能是糟糕的设计。
Where am I going wrong here? 我在哪里错了? What is the correct approach?
什么是正确的方法? Am I making a fool of myself?
我自欺欺人了吗?
The friend declaration doesn't work because WindowMgr::relocateScreen()
is private to WindowMgr
. 友元声明不起作用,因为
WindowMgr::relocateScreen()
是WindowMgr
。
C++ standard 11.4-7: C ++标准11.4-7:
"A name nominated by a friend declaration shall be accessible in the scope of the class containing the friend declaration..."
“朋友声明提名的名称应在包含朋友声明的类别范围内可访问......”
Personally, I would make relocateScreen()
a private member function of Screen
and make WindowMgr
a friend
of Screen
. 就个人而言,我会将
WindowMgr
relocateScreen()
作为Screen
的私有成员函数,并使WindowMgr
成为Screen
的friend
。 That way, WindowMgr
can just call relocateScreen()
on Screen
and won't have to touch any of the data members of Screen
. 这样,
WindowMgr
只能在Screen
上调用WindowMgr
relocateScreen()
,而不必触及Screen
任何数据成员。
The WindowMgr will have to declare Screen as a friend. WindowMgr必须将Screen声明为朋友。 You can use a forward declaration.
您可以使用前向声明。
Why not factor the WindowMgr::relocateScreen out into a different class, say WindowMgrFoo witht the 1 relocateScreen function. 为什么不将WindowMgr :: relocateScreen分解为另一个类,比如说WindowMgrFoo和1 relocateScreen函数。 Delcare WindowMgrFoo a friend of Screen in Screen and have WindowMgr inherit privately from WindowMgrFoo?
Delcare WindowMgrFoo是Screen in Screen的朋友,WindowMgr是否从WindowMgrFoo私下继承? Or just have WindowMgr have a reference to a WindowMgrFoo, but that you need to change how it's called by users if you make it public.
或者只是让WindowMgr具有对WindowMgrFoo的引用,但是如果将其公开,则需要更改用户调用它的方式。
In Silico - Nice one for citing the standard. 在Silico - 很好的引用标准。 Having slept on it I now see the rationale:
睡了之后我现在看到理由:
By declaring WindowMgr::relocateScreen
with its paramater list to be a friend in Screen
, the Screen
class becomes dependent on the private implementation of the WindowMgr
class. 通过声明
WindowMgr::relocateScreen
及其参数列表成为Screen
的朋友, Screen
类变得依赖于WindowMgr
类的私有实现。 This violates encapsulation/information hiding. 这违反了封装/信息隐藏。
In order to not violate the tenets of OOD, only public member-functions of class can be declared as friends in another, because otherwise the latter becomes dependent on the private implementation of the former. 为了不违反OOD的原则,只有类的公共成员函数可以在另一个中声明为朋友,否则后者变得依赖于前者的私有实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.