Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C++, given a member function in class A, can we restrict its access to only class B, without giving B complete friend access to A? [duplicate]

Possible Duplicate:
clean C++ granular friend equivalent? (Answer: Attorney-Client Idiom)

I've wanted this a couple times and haven't been able to come up with a decent way to do it.

Say I've got a member function in class A. I want to be able to call that function from an unrelated class B, but not be generally callable. You might say, "Sure, make the function private and declare B to be a friend of A." That's what I've been doing, but it seems a bit overkill. I don't really want to give B access to everything in A, just the one function.

In short: A::func() callable only by class B, but B not declared a friend of A. Possible?

like image 819
Kurt Hutchinson Avatar asked Jul 19 '10 16:07

Kurt Hutchinson


People also ask

Can member functions of a class be private?

Private: The class members declared as private can be accessed only by the member functions inside the class. They are not allowed to be accessed directly by any object or function outside the class. Only the member functions or the friend functions are allowed to access the private data members of the class.

Can we access private data members of a class without using a member or a friend function in C++?

Yes, it is possible using pointers. Although it's a loophole in C++, yes it's possible through pointers.

Can a member function of one class be friend function of another class?

Yes, we can write member function of one class as friend of another class. These can be one of the important uses/needs of friend function in c++.

Can we access private data members of class outside without using a friend function?

Accessing Private Data Members Outside Class is Not Possible in C++ unless a friend function is used or is accessed by a member function. So, there's no question of accessing them outside a program.


2 Answers

You could split the interface of A into several pure abstract base classes and then give B a reference to the interface that has the appropriate method. Other classes would only get interfaces that do not contain this method. Keep in mind that this is not very scalable, as the number of interfaces can quickly become very large.

like image 149
Björn Pollex Avatar answered Oct 19 '22 10:10

Björn Pollex


One possible way might be to create a trusted class that wraps A::func and pass a wrapper object to B. This again requires the wrapper to be a friend of A, but you only need to manage one such class, while all external classes can make use of the wrapper.

Example:

class Wrapper;

class A {
  private:
    void func();
    /* other methods */

  public:
    Wrapper getWrapper();

    friend class Wrapper;
};

class Wrapper {
  private:
    A &ref;

  private:
    Wrapper(A &obj) : ref(obj) { }

  public:
    void func() {
      ref.func();
    }

  friend class A;
};

Wrapper A::getWrapper() {
  return Wrapper(*this);
}
like image 24
casablanca Avatar answered Oct 19 '22 09:10

casablanca