Reputation: 2531
Is there any alternative to friendship in the following scenario?
I have a Window
class which represents an UI window. Also, a WindowManager
class, implemented as a singleton, manages all window objects in my application (renders the UI, dispatches events, etc.)
The WindowManager
will have a public interface consisting of only its singleton instancing method and functions to render the UI and to dispatch an UI event.
I would also like Window
objects to register with the WindowManager
during construction and to de-register during destruction. The WindowManager::register
and WindowManager::deregister
methods will be either private or protected, because I do not want clients (other than Window
objects) to be able use this interface.
Is there a method to avoid friendship between Window
and WindowManager
in this case? Perhaps a totally different way to achieve similar results?
Upvotes: 4
Views: 4466
Reputation: 917
Another solution (not necessary better :]) is to put the window registration to a separate component
- let's say the WindowRegister. WindowRegister can have a public interface for registration and can also be a private member of a WindowManager.
The problem with friendship is that it is not inherited
(a friend of my grandpa is not necessary my friend) - and there is a big chance that either Window or WindowManger will be polymorphic.
Regards
Upvotes: 2
Reputation: 5668
There are several other options. For example:
Or you could just make them friends. That's much easier and saner than any of the other options and why friends exist.
Upvotes: 1
Reputation: 283733
Yes, but friendship is the best solution, since it's designed for this scenario.
Another way is to make Window
a member of WindowManager
(note, this requires the new C++11 accessibility rules). Or have it derive from a member of WindowManager
. Or have it derive from WindowManager
itself.
You can also put a private type inside Window
, make a key type nested in Window
which can only be constructed from that private type, and require passing an instance of that key type to WindowManager
. This should work in pre-C++11 compilers.
Of course, any approach can be bypassed using enough casting.
Upvotes: 4
Reputation: 53067
Use nested classes.
WindowManager {
private:
static void construct();
static void destruct();
public:
class InternalWindow { // can access WindowManager's private members (no scoping needed)
InternalWindow() { construct(); }
~InternalWindow() { desstruct(); }
};
};
typedef WindowManager::InternalWindow Window; // to make scoping easier
Upvotes: 2
Reputation: 206566
Using Friend
ship seems appropriate here.You want to indicate an Intentional strong coupling between the two classes, which is aptly indicated through friends.
More specifically, one class needs access to another classes's internals and you don't want to grant access to everyone by using the public access specifier.
The rule of thumb: is public is too weak and private is too strong, you need some form of selected access: either protected or friend.
Using Friend
ship is the Best solution here.
Upvotes: 2