3

I have the following class :-

class A {
  public:
    // some stuff that everyone should see
  protected:
    // some stuff that derived classes should see
  private:
    // some stuff that only I can see
    void f();
    void g();
};

Now, I want f() to only be accessible from a certain set of classes (say classes B,C,D) and g() to be accessible from a certain other set of classes (say classes D,E,F). Is there any way to specify this in C++? If I make all the classes friends of A, then both f & g will be accessible from B,C,D,E,F (along with the other private members of A) which is not what I want.

Is this possible or should I change my object model?

owagh
  • 3,428
  • 2
  • 31
  • 53
  • 2
    AFAIK it's not possible in C++. Why not define the needed methods in interfaces, implement the interfaces in the class and feed the other classes with the interface pointer instead of class instance pointer? – Vlad May 31 '12 at 15:03
  • @Vlad I want to avoid multiple inheritance as far as possible. – owagh May 31 '12 at 15:04
  • 3
    Well, multiple inheritance on interface level is quite harmless – Vlad May 31 '12 at 15:05
  • Is it? It'll still create a virtual table and calling anything other than the first base class's virtual functions would be slightly less efficient due to thunk adjustments right?. In most cases this won't matter, but I'm working on a rather performance critical project. – owagh May 31 '12 at 15:07
  • Why do you think you need such fine grained control? – David Rodríguez - dribeas May 31 '12 at 15:08
  • @owagh: I don't think this is going to be a bottleneck, but you should see if this is the case for your project. If the performance is very important, maybe you can sacrifice the exact visibility rules? – Vlad May 31 '12 at 15:09
  • What about using inner classes to wrap f() and g()? – Stephan May 31 '12 at 15:15
  • Well it's probably bad design but I have a lot of (virtual & non-inlineable) function calls to functions small enough that the cost of calling a function is non-trivial compared to the cost of the function itself. – owagh May 31 '12 at 15:37

1 Answers1

2
class A_f {
    friend class B;
    void f();
};

class A_g {
    friend class C;
    void g();
};

class A: public A_f, public A_g {
    friend class A_f;
    friend class A_g;
private:
    void do_f();
    void do_g();
};

inline void A_f::f() { static_cast<A *>(this)->do_f(); }
inline void A_g::g() { static_cast<A *>(this)->do_g(); }

void B::something(A *a) {
    a->f();
}
ecatmur
  • 152,476
  • 27
  • 293
  • 366