12

I want to make a class A friend class of class B. I want to do this as these interact very much and A needs to change internals of class B (which I dont want to expose using public). But I want to make sure it has access to only a few selected functions not all the functions.

Example:

class A
{
};

class B
{
private:
 void setState();
void setFlags();
friend class A
};

I want A to be able to access setState but not setFlags... Is there a design pattern or a nice way of doing this or am I left with giving full access or no access at all in this case.

Thanks

Zed
  • 57,028
  • 9
  • 76
  • 100
VNarasimhaM
  • 1,460
  • 3
  • 22
  • 36
  • Apart from the fact that you could customize your account (there are so many unknown...), that's a very interesting question indeed. I am still toying with the Key and the Private Interface at the moment! – Matthieu M. Oct 23 '09 at 12:30

3 Answers3

28

It depends on what you mean by "a nice way" :) At comp.lang.c++.moderated we had the same question a while ago. You may see the discussion it generated there.

IIRC, we ended up using the "friend of a nested key" approach. Applied to your example, this would yield:

class A
{
};

class B
{
public:
     class Key{
         friend class A;
         Key();
     };

    void setFlags(Key){setFlags();}         

private:
  void setState();
  void setFlags();
};

The idea is that the public setFlags() must be called with a "Key", and only friends of Key can create one, as its ctor is private.

Éric Malenfant
  • 13,938
  • 1
  • 40
  • 42
  • Really clever. I usually relied on a 'contract' since I had not fought of any way to this... you learn every day! – Matthieu M. Oct 23 '09 at 10:35
  • By the way, in the OP question, he wanted to access setState, not setFlags... yes I am pedantic... – Matthieu M. Oct 23 '09 at 10:47
  • I've been thinking about it... why make Key a nested class of B ? Doesn't it prevent forward declaration and thus provokes a dependency (A's header will need to include B's header to have Key) ? I think perhaps using a nested namespace here (the famous detail) could be better. – Matthieu M. Oct 23 '09 at 12:22
  • Is there a way to restrict friends' access on a few data members, rather than method members as described in this solution? – user3528438 Oct 12 '15 at 01:24
  • Damn that's brilliant!! – djfm Sep 06 '21 at 14:36
7

One approach is through explicit interfaces, because the implementor of an interface can select who they give them to:

class NearlyPrivateInterface {
public:
   virtual void setState() = 0;
   virtual void setFlags() = 0;
};

class A {
public:
   void attach(NearlyPrivateInterface* instanceOfB);
};

class B: private NearlyPrivateInterface {
public:
   void attach(A& a) { a.attach(this); }
};
Will
  • 73,905
  • 40
  • 169
  • 246
1

You can do following thing..

class A{
};

class B{
private: 
    void setFlags();
protected:
    void setState();

}; 

class RestrictedB :public B{  
    friend class A;
};
Richard Corden
  • 21,389
  • 8
  • 58
  • 85
Ashish
  • 8,441
  • 12
  • 55
  • 92