Humam Helfawi
Humam Helfawi

Reputation: 20284

Granting access on a function to another class without exposing it

I have a class let us call it Person:

class Person{
private:
    void move(x,y,z);
}

I have another class called PersonController:

class PersonController{
public:
    void control(){
        while(some_thing){
             //do some calculations
             controlled_person_->move(some_values); //Wrong Accessing to a private member
        }
    }
private:
    Person* controlled_person_;
}

Both Person and PersonController are part of the public interface of the library I am designing.

I want PersonController to be able to call move from Person. However, I do not want anyone to access this function (move) from the public interface.

The easy way to sovle the problem is add a friendship so PersonController can access private members of Person. However, as far as I read the friend keyword was not introduced to solve these kind of problems and using it here would be a bad practice.

Upvotes: 1

Views: 788

Answers (3)

From what you said in comments, it seems you are interested in only allowing PersonController to touch that one member function. The way to do that and only that, is to make the door public, but add a private key for it:

class Person{
public:
    class MovePrivilege {
        move_privilege() = default; // private c'tor
        friend class PersonController; // only PersonController may construct this
    }; 

    void move(MovePrivilege, x,y,z);
};

class PersonController{
public:
    void control(){
        while(some_thing){
             //do some calculations
             controlled_person_->move(MovePrivilege{} , some_values);
        }
    }
private:
    Person* controlled_person_;
};

The type MovePrivilege has a private c'tor. So it can only be constructed by its friends. And it is also required for calling move. So while move is public, the only classes that may call it are the friends of MovePrivilege.

This essentially gives you a fine grained control over who may call move. If this is obtrusive and you can't change move itself, a variant of the attorney client idiom may be appropriate instead.

You do have options at your disposal. Direct firend-ship is just the bluntest tool.

Upvotes: 6

M4HdYaR
M4HdYaR

Reputation: 1164

Yes your design is not correct.

Classes are an expanded concept of data structures: like data structures, they can contain data members, but they can also contain functions as members. You can read more here

So PersonController (If it only control person class) should not be a class because it is not concept of data structures Check if it is possible to merge them or design another way.

There are many ways to do it.If you want to design it like what you do now you can use protected access controller for your function and Create derived class but it's not a good design again.

You can use friend function here too but it isn't an object oriented concept again(But the easiest way).

You should rethink about your design if you want to design it OO.Because you can't access private function from other class in object oriented programming ,It breaks encapsulation so C++ won't let you do that.

However your question depends on opinions too.

Upvotes: -1

SoronelHaetir
SoronelHaetir

Reputation: 15172

That is exactly the sort of problem that friend is meant for. While friendship should be minimized if your design needs it there is no reason not to use it.

I see non-use of friend a lot like the continuing dislike of 'goto', there are simply times where using it will make a design far cleaner.

Upvotes: 1

Related Questions