Question

I'm sure there is a better way to design this:

I have a class whose main purpose in life is to look after other classes which look after smaller things. These smaller classes have a limited amount of public data, a few methods which should only be accessible from the manager class, and a group of internal functions which should only be accessible from itself.

I was going to make the manager class a friend, but this will allow the manager to see (and use) the internal functions of the smaller class, which isn't ideal.

class child
{
public:
  int x;
private:
  friend class manager;
  doSomething();
  internalWork();
};

class manager
{
  public:
    child c;
};

manager m;

int i = m.c.x; // OK
c.doSomething(); // From method inside 'manager': OK
c.internalWork(); // Not allowed, only 'child' can use this function

Any ideas?

Was it helpful?

Solution

I program for a living; I work at a software company. I have a boss who will occasionally give me a task to do.

When he gives me a task, he simply says "Go write this widget, then commit it to source control. Then tell QA to test it."

What he doesn't do is tell me "Go write this widget, then commit it to source control. Then tell QA to test it," and then come over to my desk and start writing code. He's telling me what to do -- not doing it himself.

But that's basically what your manager class is doing when you do: c.internalWork(); -- the manager isn't telling the child object what to do; the manager is doing it.

friends are a code smell. They aren't necessarily a bad thing, and they certainly have their uses -- but they are the kind of thing that should make you sit back and think, "Do we really need this here?" In this case, the use of friend is a hack around a design flaw. The design flaw is the fact that your child classes don't have a public interface through which the manager can tell them what to do. The hack is the fact that your manager class is just throwing it's hands up and doing the work itself.

Fix your classes so that they have a proper interface, and get rid if the friendship.

OTHER TIPS

Does anything other than manager need to see the child class at all? Why not hide child's implementation completely so that it's only accessible from manager using the pimpl idiom?

If this is unacceptable, why did you couple child's member functions to the public data at all? Why not make it a structure with only public data members, together with a bunch of free functions for manipulating those data members? Then you can control access to said free functions in a similar way, by only making them visible within the translation units where manager's implementation lives.

Manager is not the Child, and not a friend of the child. He is a Manager. The Manager needs an interface from the child to be able to manage, or to be more specific to tell the Child what to do, and to learn when the job is done, but he does not need to micro manage, he has no need to see the internal data of the child. The child need to protect its internal data, but it needs the public interface to get the task from the Manager, and nobody but the Manager, and needs to be able to tell the manager when the task is done.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top