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
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.
Making the relocateScreen
function public might be bad 开发者_Python百科design if it's intented only for use within the WindowMgr
class. 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.
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
.
C++ standard 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
. That way, WindowMgr
can just call relocateScreen()
on Screen
and won't have to touch any of the data members of Screen
.
The WindowMgr will have to declare Screen as a friend. You can use a forward declaration.
Why not factor the WindowMgr::relocateScreen out into a different class, say WindowMgrFoo witht the 1 relocateScreen function. Delcare WindowMgrFoo a friend of Screen in Screen and have WindowMgr inherit privately from 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.
In Silico - Nice one for citing the standard. 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. 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.
精彩评论