I have two closely related classes which I'll call Widget and Sprocket. Sprocket has a set of methods which I want to be callable from Widget but not from any other class. I also don't want to just declare Widget a friend of Spocket because that would give Widget access to ALL protected and private members. I want to restrict Widget's access to only a specific set of methods.
One solution I came up with is to create a nested class inside Sprocket that contains wrappers for these methods and make Widget a friend of this nested class. For example:
class Sprocket
{
public:
class WidgetInterface
{
friend class Widget;
WidgetInterface(Sprocket* parent) : mParent(parent) {}
private:
void A() { mParent->A(); }
void B() { mParent->B(); }
Sprocket* mParent;
};
private:
void A() { ... }
void B() { ... }
};
class Widget
{
public:
Widget(Sprocket* sprock) : mSprocketIface(sprock) {}
void doStuff() { mSprocketIface.A(); } // Widget can call Sprocket::A()
private:
Sprocket::WidgetInterface mSprocketIface;
};
This results in some code duplication because the method signatures are now declared in two places, but it works. But now suppose I want to add a subclass of Widget called SpecialWidget and I want that class to also have access to the Sprocket methods. I can simply add this new class to the Sprocket friends list or I can add yet another set of protected wrappers in Widget that SpecialWidget (and any other subclass) can access but you can see that this is now becoming a maintenance issue. I don't want to have to update the friends list or the wrappers if I add new classes or change the method signature. If I use the "add another set of wrappers" approach, the method signatures will be duplicated in three places!
Does anyone know of a simpler, cleaner way to do this?