Search code examples
c++encapsulation

Restricting method call to a specific class


class A : public Interface
{
 public:
     void doAction();

     void interfaceMethod1();
     ...
}
class AExt
{
public:
   void doAction();
private:
    int m_state;
}

I have the class A which can doAction() and also implementing Interface (Interface doesn't include doAction). A works fine, so I'd like minimize changes in A. Now I want to add the new state and create the class AExt which now takes responsibility of making doAction(), which changes the state and now depends on the state. The goal is to restrict doAction() so that it can be called ONLY by AExt, because calling A::doAction not from AExt will break the functionality. At the same time AExt uses only public interface of A.

  1. I can make doAction() private and make AExt friend of A, but I don't like this because it will expose all A's internals to AExt;
  2. I can make doAction() virtual and inherit AExt from A, same problem. In addition there will (probabaly) be A successor's who do not want to know whether there is A or AExt.
  3. I can use the same interface for A and AExt and use Decorator pattern, but I don't like this because A has many additional methods (all the Interface) which AExt doesn't need, and clients of A need them.
  4. I can use composition as follows but this will not prevent calling of A::doAction() from outside.

    class AExt { public: void doAction() { m_a.doAction(); ... } A& getA() { return m_a; } }

suggestions?


Solution

  • Vlad, C++ does not provide fine granularity that you want. You are basically right with your approaches 1-4. Attempt to add such fine details into C++ will result in an even more complex language. Some say that C++ is already too complex. This means that language design is a trade of between expressability and desire to keep it reasonably simple.

    I would declare your doAction(); protected. This will prohibit from calling it from arbitrary piece of code. At the same time it seems that AExt is your own class. Maybe it is not so terribly bad if it will have full access to its parent. This solution is not perfect from all points of view. It's main advantage is simplicity. I would recommend you to not over-complicate your code without good reason for that. Simplicity and clarity of the code is also important.