Reputation: 20284
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.
friend
here?Upvotes: 1
Views: 788
Reputation: 170163
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
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
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