Is there a way to make a public member function private to certain classes? The reason I need to do this is because some classes must use something else in place of that public member function, else there will be serious bugs, but it is easy to forget and do that anyway. Example:
class Location {
std::list<Person*> everyonePresent;
public:
const std::list<Person*>& getEveryonePresent() const {return everyonePresent;}
};
class DoSomething {
Person& person;
std::list<Person*> everyoneVisible;
public:
DoSomething(Person& p) : person(p), everyoneVisible(p.getLocation().getEveryonePresent()) {
// everyoneVisible now removes those who are hiding.
}
void execute() {
// ....
ApproachSomeone(person, everyoneVisible).execute();
// ...
}
};
Now ApproachSomeone::execute() may accidentally use person.getLocation().getEveryonePresent() when it is not supposed to. But Location::getEveryonePresent() needs to be public because it is used in so many places, but ApproachSomeone is one of the few classes that must never use it. ApproachSomeone is a class because it is used in many other places (command pattern).
There is a way to model access on a per function basis if you are willing to do some dependency injection, or willing to do an explicit cast of a class to an abstract base class to gain access to private member functions.
I have used these approaches in cases where a class would need more then one "friend", but those friends should have distinct access to various member functions. It is still easier to do the correct thing, but not impossible to get "private" access. It is a good compromise and code can be checked on who gets access to what (so it is possible to detect misuse in code reviews too).
Live demo here: https://onlinegdb.com/TFVGm-HVW
First, we make two interfaces for per-class access to a
class A:Then, make a
class Awhich inherits from both, but keeps the implementationprivate. This hides the member functions from everyone.Then, use dependency injection:
class Breceivesinterface_for_class_bclass Creceivesinterface_for_class_cHere is how we use these classes: