3

I have a class A which has a private method called a(). I have also a class B which needs to access a() (but just B should have access to a(), thats why a() is private). I could now use a friend specifier but that would make other private methods of A (lets call them b() and c()) also available to B and I dont want that behaviour.

Is there a way to make just a() of A accessable to B?

Sebastian Hoffmann
  • 11,127
  • 7
  • 49
  • 77
  • 3
    See this question: http://stackoverflow.com/questions/1609472/friend-class-with-limited-access – Asaf Jan 02 '12 at 12:42

4 Answers4

4

There is a way -- if your class has a public template function:

class A {
    // apparently private
    void priv () { std::cout << "got you A::a()" << std::endl ; }
public:
    template <class T> 
    void abuse() {}
    };


struct Thief {};

template <>
void A::abuse<Thief>() {
    this->priv();
    }

int main() {
    A a;
    // obviously do not compile :   a.priv();
    // this i OK
    a.abuse<Thief>();

    return 0;
    }

I must confess I stole this from GotW...

reder
  • 1,098
  • 7
  • 9
1

No there's not, but as you specify the precise class, just B could access A's private members. You just have to take care of what method are called.

As friend relationship are not inherited, you don't have to worry about B's possible subclasses.

Jaffa
  • 12,442
  • 4
  • 49
  • 101
0

This could be done with some "twist".

Just factor out method a() from A class into a parent class that has B as a friend class, then let A inherit it. this will leave a() as being a method in A, but the only private method accessible by its parent's friend B.

here is a very simple code to clarify what I've said:

class parent
{
    friend class B;
private:
    void a() {}
};

class A:public parent
{
private:
    void b() {}
    void c() {}
};


class B
{
    A* m_a;
public :
    B() 
    {
        m_a = new A();
        m_a->a(); // OK
        m_a->b(); //  error C2248: 'A::b' : cannot access private member declared in class 'A'

    }
};

hope it helps !

Assem
  • 516
  • 3
  • 10
  • Nice idea, although one could get problems if the private functions in parent are not standalone and need to access methods or members of A (which is required pretty often). See the link provided by Asaf. In there is a nice solution; thats why i accepted this question. – Sebastian Hoffmann Jan 02 '12 at 13:03
0

Yes, I have an easy way. Let B have a pointer of A::a(), like this:

typedef boost::function<void ()> functype;

class A {        
private:
    void a();
};

class B {
public:
    void setfp(functype f) {m_f = f;}
    void foo() {
        // do some stuff
        m_f();
    }
private:
    functype m_f;
};

A a;
B b;
b.setfp(boost::bind(&A::a, &a));
b.foo();
superK
  • 3,932
  • 6
  • 30
  • 54
  • There are a few problems with this at first glance. Since `A::a` is private, your call to `setfp()` will not compile. This puts you back at square 1. Also, while (almost) giving partial access to private members, it now gives it to anyone, not just `B`. So I don't see how the OP could actually use this solution to practically solve the problem. – tenfour Jan 02 '12 at 14:54