Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allowing a "friend" class to access only some private members

Tags:

c++

friend

Suppose I have three C++ classes FooA, FooB and FooC.

FooA has an member function named Hello, I want to call this function in class FooB, but I don't want class FooC be able to call it. The best way I can figure out to realize this is to declare FooB as a friend class of FooA. But as long as I do this, all FooA's private and protected members will be exposed which is quite unacceptable to me.

So, I wanna know if there is any mechanism in C++(03 or 11) better than friend class which can solve this dilemma.

And I assume it will be nice if the following syntax is possible:

class FooA { private friend class FooB:     void Hello();     void Hello2(); private:     void Hello3();     int m_iData; };  class FooB {     void fun()     {         FooA objA;         objA.Hello()  // right         objA.Hello2() // right         objA.Hello3() // compile error         ojbA.m_iData = 0; // compile error     } };  class FooC {     void fun()     {         FooA objA;         objA.Hello()  // compile error         objA.Hello2() // compile error         objA.Hello3() // compile error         ojbA.m_iData = 0; // compile error     } }; 
like image 783
Archer Avatar asked Apr 17 '13 08:04

Archer


2 Answers

There's nothing to make a class a friend of one specific function, but you can make FooB a friend of a "key" class with private constructor, and then have FooA::Hello take that class as an ignored parameter. FooC will be unable to provide the parameter and hence can't call Hello:

Is this key-oriented access-protection pattern a known idiom?

like image 196
Steve Jessop Avatar answered Sep 27 '22 23:09

Steve Jessop


I think you can use Attorney-Client here.

In your case example should be like this

class FooA { private:     void Hello();     void Hello2();     void Hello3();     int m_iData;      friend class Client; };  class Client { private:    static void Hello(FooA& obj)    {       obj.Hello();    }    static void Hello2(FooA& obj)    {       obj.Hello2();    }    friend class FooB; };  class FooB {     void fun()     {         FooA objA;         Client::Hello(objA);  // right         Client::Hello2(objA); // right         //objA.Hello3() // compile error         //ojbA.m_iData = 0; // compile error     } };  class FooC {     void fun()     {         /*FooA objA;         objA.Hello()  // compile error         objA.Hello2() // compile error         objA.Hello3() // compile error         ojbA.m_iData = 0; // compile error*/     } }; 
like image 27
ForEveR Avatar answered Sep 27 '22 23:09

ForEveR