Reputation: 33
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 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?
Upvotes: 3
Views: 635
Reputation: 33
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.
Upvotes: 0
Reputation: 52179
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
.
Upvotes: 1
Reputation: 11473
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.
Upvotes: 0
Reputation: 146968
The WindowMgr will have to declare Screen as a friend. You can use a forward declaration.
Upvotes: 0