0

Assume you have two classes, a Manager who holds a set of Clients and the Client holds a backreference to the Manager.

class Manager {
public:
    void addClient(Client* client) {
        m_clients.push_back(client);
        client->setManager(this);
    }
private:
    std::list<Client*> m_clients;
};

class Client {
public:
    void setManager(Manager* manager) {
        m_manager = manager;
    }

private:
    Manager* m_manager;
};

The confusing, probably even dangerous feature of this API is that Client exposes a setManager() method that can be called by anyone, yet should only be called by the Manager::addClient() method.

assert(manager->hasClient(this)) in setManager() would prevent wrong calling at runtime, however I would prefer a solution that doesn't allow the user to call methods he isn't supposed to call.

What would be common solution? I don't

  • want to use friend to expose all of Clients members to Manager so that he can establish the binary connection in addChild()
  • want both classes to share some kind of Composite base class. They should remain unrelated inheritancewise.
hllnll
  • 199
  • You should change the question to A solution that doesn't allow the user to call methods he isn't supposed to call. Have a look at Facade, Interface, Proxy, Adaptor, Bridge. I would also say you can name the method do_never_call_me_unless_you_know_what_for_add_client – User May 14 '14 at 15:08
  • Could you simply check in setManager() whether m_manager has already been set? – Greg Hewgill May 14 '14 at 20:09

1 Answers1

1

One fairly standard approach would be to make Client::setManager protected and declare Manager::addClient as a friend function in Client. This will allow Manager::addClient access to all of Client's private and protected members, not just Client::setManager, but is more encapsulated overall than a public Client::setManager.

See also:

outis
  • 1,171