Restrict method access to a specific class in C++ - c++

I have two closely related classes which I'll call Widget and Sprocket. Sprocket has a set of methods which I want to be callable from Widget but not from any other class. I also don't want to just declare Widget a friend of Spocket because that would give Widget access to ALL protected and private members. I want to restrict Widget's access to only a specific set of methods.
One solution I came up with is to create a nested class inside Sprocket that contains wrappers for these methods and make Widget a friend of this nested class. For example:
class Sprocket
{
public:
class WidgetInterface
{
friend class Widget;
WidgetInterface(Sprocket* parent) : mParent(parent) {}
private:
void A() { mParent->A(); }
void B() { mParent->B(); }
Sprocket* mParent;
};
private:
void A() { ... }
void B() { ... }
};
class Widget
{
public:
Widget(Sprocket* sprock) : mSprocketIface(sprock) {}
void doStuff() { mSprocketIface.A(); } // Widget can call Sprocket::A()
private:
Sprocket::WidgetInterface mSprocketIface;
};
This results in some code duplication because the method signatures are now declared in two places, but it works. But now suppose I want to add a subclass of Widget called SpecialWidget and I want that class to also have access to the Sprocket methods. I can simply add this new class to the Sprocket friends list or I can add yet another set of protected wrappers in Widget that SpecialWidget (and any other subclass) can access but you can see that this is now becoming a maintenance issue. I don't want to have to update the friends list or the wrappers if I add new classes or change the method signature. If I use the "add another set of wrappers" approach, the method signatures will be duplicated in three places!
Does anyone know of a simpler, cleaner way to do this?

If you have two tightly coupled classes, then it's really not worth trying to make friend access any more granular than it is. You control the implementation of both, and you should trust yourself enough to not abuse the ability to call some methods that you don't, strictly speaking, need to call.
If you want to make it clear for future code maintainers, add a comment to the friend declaration explaining why it is there (a good idea in general), and what private methods are allowed to be called by the friend class.

Sprocket has a set of methods which I want to be callable from Widget but not from any other class.
Why not save yourself some trouble & implement this set of methods in Widget, perhaps adding a Sprocket parameter to these methods?

I would have implemented WidgetInterface as a real interface inherited by Sprocket, so A and B are all that Widget know about. Okay, other can use that interface too, but they probably will have a reason for this.

The secret is all this access control is pointless and illusionary, and there's no way to really limit any access to anything. You are just complicating things and making it difficult to figure out what parts of widget are ok to use and what parts are not. Instead, make the interface for widget and sprocket more obvious, and perhaps have widget own a private sprocket. If people are so clueless that they will violate this there's no help for it, but if you make something abominable and hard to figure out it guarantees even people who know C++ well will be unable to easily make use of it.

Related

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.
Is this correct? Should I avoid friend here?
Does this mean my design is broken?
Any alternative suggestions?
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.
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.
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.

Can some members of a class be accessible only by base classes?

I have a Widget class and a CompositeWidget that is derived from it. CompositeWidget adds child management behaviour. The Widget constructor takes a CompositeWidget* parameter as the widget parent. I need to use this parent pointer to access some functionality within the CompositeWidget. For example:
Widget::Widget(CompositeWidget* parent)
{
parent_->AddChild(*this);
}
This forces me to create a public method CompositeWidget::AddChild. Is is possible to keep this interface private to the class hierarchy (a little like a reverse-protected access - limited to base classes)? Am I making a design faux pas in thinking about the problem like this?
Edit: I am trying to avoid friendship (if it's possible in this case).
This forces me to create a public method
No, you could declare:
friend class Widget;
In the CompositeWidget declaration. However...
Am I making a design faux pas
Having a parent class method that references a derived class has a whiff of design flaw in it, perhaps, but I won't say it's categorically wrong.
Use the friend keyword.
class Widget { ... };
class CompositeWidget {
friend class Widget;
};
However, you can alternatively insert the virtual method AddChild on the Widget class.
Answer to your concrete question: declare Widget to be a friend of your CompositeWidget and make AddChild a private member.
Alternatively, move the child management to CompositeWidget. The Design Patterns book has an extended discussion on this in their section on the Composite Pattern:
The decision involves a trade-off between safety and transparency:
Defining the child management interface at the root of the class hierarchy gives you transparency, because you can treat all components uniformly. It costs you safety, however, because clients may try to do meaningless things like add and remove objects from leaves.
Defining child management in the Composite class gives you safety, because any attempt to add or remove objects from leaves will be caught at compile-time in a statically typed language like C++. But you lose transparency, because leaves and composites have different interfaces.
We have emphasized transparency over safety in this pattern. If you
opt for safety, then at times you may lose type information and have
to convert a component into a composite. How can you do this without
resorting to a type-unsafe cast?
They go on to give a long code example, which essentially boils down to this design where the CompositeWidget contains the child management:
class Widget
{
public:
//
virtual Composite* GetComposite() { return 0; }
}
class CompositeWidget: public Widget
{
public:
void AddChild(Component*);
// ...
virtual Composite* GetComposite() { return this; }
};
class LeafWidget: public Widget
{
// no child management here
};
GetComposite lets you query a widget to see if it's a composite. You
can perform AddChild safely on the composite it returns.

Class interface query

I've been wondering about a design that I've been using for quite some time for my game engine and games. Let's say we have an Object class
class Object
{
public:
const std::string& getName() { return m_name; }
private:
std::string m_name;
}
Then, I have a class called ObjectManager, which holds an instance of Object. Now, I've been wondering if I should keep that instance private in ObjectManager and duplicate code so that it could call getName(), or make Object public which defeats the concept of encapsulation. Which design do you guys think is better?
Thanks for any help!
If your class contains an object that is usable by others, expose it. Encapsulation is meant to hide variables needed to do something. Certain data members don't fall into this.
Example:
Person tom;
tom.getEyes().getColor();
tom.getMouth().eat(tomato);
tom.legs().walk();
Person could hide everything but it would be cumbersome:
tom.getEyesColor(); // accessor for every eye feature
tom.eat(tomato);
tom.walkAndEat(); // every possible combination of actions
Further example:
grid.row(3).col(5).setText("hello");
Here a column class could expose many methods without the grid class having to be touched. This is the beauty of object oriented programming.
If you named your class ObjectManager i get the feeling it is managing Object instances for others so you ought to expose it. The other idea to use inheritance is also valid:
class ObjectManager : public Object
{
};
If you want to restrict the interface to methods only then keep the object private and use an accessor method that returns a const reference (and non const if needed) to the private object.
Also, inheritance is a good option if applicable.
It depends on what you're doing. If I understand your question correctly, I'd personally lean more towards making the Object a private member of ObjectManager and adding a function to ObjectManager to act as a proxy for Object::getName(). (Is this your question?) However if you're just wrapping particularly thinly and are not trying to do something particularly technical or what have you, I might be tempted to answer otherwise. It depends, but more than likely, go ahead and make it private and add the extra function. Note that this answer is based on the assumption that you're going to make heavy use out of inheritance here.
It really depends on the situation (Sorry for the non-answer!). If you do want to support strong encapsulation, you would probably want ObjectManager to look something like this:
public class ObjectManager
{
private:
Object obj;
public:
string GetNameOfInnerObject();
}
As you can see I changed the method header to be descriptive with respect to ObjectManager. This type of method naming can come in handy to abstract an object's more complex interactions within itself away.
Edit: It might help if you tell us what ObjectManager is supposed to do. Does it have any methods that don't correspond directly to your inner object?

Can someone explain the benefits of polymorphism?

So I understand pretty much how it works, but I just can't grasp what makes it useful. You still have to define all the separate functions, you still have to create an instance of each object, so why not just call the function from that object vs creating the object, creating a pointer to the parent object and passing the derived objects reference, just to call a function? I don't understand the benefits of taking this extra step.
Why do this:
class Parent
{
virtual void function(){};
};
class Derived : public Parent
{
void function()
{
cout << "derived";
}
};
int main()
{
Derived foo;
Parent* bar = &foo;
bar->function();
return -3234324;
}
vs this:
class Parent
{
virtual void function(){};
};
class Derived : public Parent
{
void function()
{
cout << "derived";
}
};
int main()
{
Derived foo;
foo.function();
return -3234324;
}
They do exactly the same thing right? Only one uses more memory and more confusion as far as I can tell.
Both your examples do the same thing but in different ways.
The first example calls function() by using Static binding while the second calls it using Dynamic Binding.
In first case the compiler precisely knows which function to call at compilation time itself, while in second case the decision as to which function should be called is made at run-time depending on the type of object which is pointed by the Base class pointer.
What is the advantage?
The advantage is more generic and loosely coupled code.
Imagine a class hierarchy as follows:
The calling code which uses these classes, will be like:
Shape *basep[] = { &line_obj, &tri_obj,
&rect_obj, &cir_obj};
for (i = 0; i < NO_PICTURES; i++)
basep[i] -> Draw ();
Where, line_obj, tri_obj etc are objects of the concrete Shape classes Line, Triangle and so on, and they are stored in a array of pointers of the type of more generalized base class Shape.
This gives the additional flexibility and loose coupling that if you need to add another concrete shape class say Rhombus, the calling code does not have to change much, because it refers to all concrete shapes with a pointer to Base class Shape. You only have to make the Base class pointer point to the new concrete class.
At the sametime the calling code can call appropriate methods of those classes because the Draw() method would be virtual in these classes and the method to call will be decided at run-time depending on what object the base class pointer points to.
The above is an good example of applying Open Closed Principle of the famous SOLID design principles.
Say you want someone to show up for work. You don't know whether they need to take a car, take a bus, walk, or what. You just want them to show up for work. With polymorphism, you just tell them to show up for work and they do. Without polymorphism, you have to figure out how they need to get to work and direct them to that process.
Now say some people start taking a Segway to work. Without polymorphism, every piece of code that tells someone to come to work has to learn this new way to get to work and how to figure out who gets to work that way and how to tell them to do it. With polymorphism, you put that code in one place, in the implementation of the Segway-rider, and all the code that tells people to go to work tells Segway-riders to take their Segways, even though it has no idea that this is what it's doing.
There are many real-world programming analogies. Say you need to tell someone that there's a problem they need to investigate. Their preferred contact mechanism might be email, or it might be an instant message. Maybe it's an SMS message. With a polymorphic notification method, you can add a new notification mechanism without having to change every bit of code that might ever need to use it.
polymorphism is great if you have a list/array of object which share a common ancestor and you wich to do some common thing with them, or you have an overridden method. The example I learnt the concept from, use shapes as and overriding the draw method. They all do different things, but they're all a 'shape' and can all be drawn. Your example doesn't really do anything useful to warrant using polymorphism
A good example of useful polymorphism is the .NET Stream class. It has many implementations such as "FileStream", "MemoryStream", "GZipStream", etcetera. An algorithm that uses "Stream" instead of "FileStream" can be reused on any of the other stream types with little or no modification.
There are countless examples of nice uses of polymorphism. Consider as an example a class that represents GUI widgets. The most base classs would have something like:
class BaseWidget
{
...
virtual void draw() = 0;
...
};
That is a pure virtual function. It means that ALL the class that inherit the Base will need to implement it. And ofcourse all widgets in a GUI need to draw themselves, right? So that's why you would need a base class with all of the functions that are common for all GUI widgets to be defined as pure virtuals because then in any child you will do like that:
class ChildWidget
{
...
void draw()
{
//draw this widget using the knowledge provided by this child class
}
};
class ChildWidget2
{
...
void draw()
{
//draw this widget using the knowledge provided by this child class
}
};
Then in your code you need not care about checking what kind of widget it is that you are drawing. The responsibility of knowing how to draw itself lies with the widget (the object) and not with you. So you can do something like that in your main loop:
for(int i = 0; i < numberOfWidgets; i++)
{
widgetsArray[i].draw();
}
And the above would draw all the widgets no matter if they are of ChildWidget1, ChildWidget2, TextBox, Button type.
Hope that it helps to understand the benefits of polymorphism a bit.
Reuse, generalisation and extensibility.
I may have an abstract class hierarchy like this: Vehicle > Car. I can then simply derive from Car to implement concrete types SaloonCar, CoupeCar etc. I implement common code in the abstract base classes. I may have also built some other code that is coupled with Car. My SaloonCar and CoupeCar are both Cars so I can pass them to this client code without alteration.
Now consider that I may have an interface; IInternalCombustionEngine and a class coupled with with this, say Garage (contrived I know, stay with me). I can implement this interface on classes defined in separate class hierarchies. E.G.
public abstract class Vehicle {..}
public abstract class Bus : Vehicle, IPassengerVehicle, IHydrogenPowerSource, IElectricMotor {..}
public abstract class Car : Vehicle {..}
public class FordCortina : Car, IInternalCombustionEngine, IPassengerVehicle {..}
public class FormulaOneCar : Car, IInternalCombustionEngine {..}
public abstract class PowerTool {..}
public class ChainSaw : PowerTool, IInternalCombustionEngine {..}
public class DomesticDrill : PowerTool, IElectricMotor {..}
So, I can now state that an object instance of FordCortina is a Vehicle, it's a Car, it's an IInternalCombustionEngine (ok contrived again, but you get the point) and it's also a passenger vehicle. This is a powerful construct.
The poly in polymorphic means more than one. In other words, polymorphism is not relevant unless there is more than one derived function.
In this example, I have two derived functions. One of them is selected based on the mode variable. Notice that the agnostic_function() doesn't know which one was selected. Nevertheless, it calls the correct version of function().
So the point of polymorphism is that most of your code doesn't need to know which derived class is being used. The specific selection of which class to instantiate can be localized to a single point in the code. This makes the code much cleaner and easier to develop and maintain.
#include <iostream>
using namespace std;
class Parent
{
public:
virtual void function() const {};
};
class Derived1 : public Parent
{
void function() const { cout << "derived1"; }
};
class Derived2 : public Parent
{
void function() const { cout << "derived2"; }
};
void agnostic_function( Parent const & bar )
{
bar.function();
}
int main()
{
int mode = 1;
agnostic_function
(
(mode==1)
? static_cast<Parent const &>(Derived1())
: static_cast<Parent const &>(Derived2())
);
}
Polymorphism is One of the principles OOP. With polymorphism you can choose several behavior in runtime. In your sample, you have a implementation of Parent, if you have more implementation, you can choose one by parameters in runtime. polymorphism help for decoupling layers of application. in your sample of third part use this structers then it see Parent interface only and don't know implementation in runtime so third party independ of implementations of Parent interface. You can see Dependency Injection pattern also for better desing.
Just one more point to add. Polymorphism is required to implement run-time plug-ins. It is possible to add functionality to a program at run-time. In C++, the derived classes can be implemented as shared object libraries. The run time system can be programmed to look at a library directory, and if a new shared object appears, it links it in and can start to call it. This can also be done in Python.
Let's say that my School class has a educate() method. This method accepts only people who can learn. They have different styles of learning. Someone grasps, someone just mugs it up, etc.
Now lets say I have boys, girls, dogs, and cats around the School class. If School wants to educate them, I would have to write different methods for the different objects, under School.
Instead, the different people Objects (boys,girls , cats..) implement the Ilearnable interface. Then, the School class does not have to worry about what it has to educate.
School will just have to write a
public void Educate (ILearnable anyone)
method.
I have written cats and dogs because they might want to visit different type of school. As long as it is certain type of school (PetSchool : School) and they can Learn, they can be educated.
So it saves multiple methods that have the same implementation but different input types
The implementation matches the real life scenes and so it's easy for design purposes
We can concentrate on part of the class and ignore everything else.
Extension of the class (e.g. After years of education you come to know, hey, all those people around the School must go through GoGreen program where everyone must plant a tree in the same way. Here if you had a base class of all those people as abstract LivingBeings, we can add a method to call PlantTree and write code in PlantTree. Nobody needs to write code in their Class body as they inherit from the LivingBeings class, and just typecasting them to PlantTree will make sure they can plant trees).

Alternative to friendship?

Is there any alternative to friendship in the following scenario?
I have a Window class which represents an UI window. Also, a WindowManager class, implemented as a singleton, manages all window objects in my application (renders the UI, dispatches events, etc.)
The WindowManager will have a public interface consisting of only its singleton instancing method and functions to render the UI and to dispatch an UI event.
I would also like Window objects to register with the WindowManager during construction and to de-register during destruction. The WindowManager::register and WindowManager::deregister methods will be either private or protected, because I do not want clients (other than Window objects) to be able use this interface.
Is there a method to avoid friendship between Window and WindowManager in this case? Perhaps a totally different way to achieve similar results?
Yes, but friendship is the best solution, since it's designed for this scenario.
Another way is to make Window a member of WindowManager (note, this requires the new C++11 accessibility rules). Or have it derive from a member of WindowManager. Or have it derive from WindowManager itself.
You can also put a private type inside Window, make a key type nested in Window which can only be constructed from that private type, and require passing an instance of that key type to WindowManager. This should work in pre-C++11 compilers.
Of course, any approach can be bypassed using enough casting.
Using Friendship seems appropriate here.You want to indicate an Intentional strong coupling between the two classes, which is aptly indicated through friends.
More specifically, one class needs access to another classes's internals and you don't want to grant access to everyone by using the public access specifier.
The rule of thumb: is public is too weak and private is too strong, you need some form of selected access: either protected or friend.
Using Friendship is the Best solution here.
Use nested classes.
WindowManager {
private:
static void construct();
static void destruct();
public:
class InternalWindow { // can access WindowManager's private members (no scoping needed)
InternalWindow() { construct(); }
~InternalWindow() { desstruct(); }
};
};
typedef WindowManager::InternalWindow Window; // to make scoping easier
Another solution (not necessary better :]) is to put the window registration to a separate component - let's say the WindowRegister. WindowRegister can have a public interface for registration and can also be a private member of a WindowManager.
The problem with friendship is that it is not inherited (a friend of my grandpa is not necessary my friend) - and there is a big chance that either Window or WindowManger will be polymorphic.
Regards
There are several other options. For example:
You could use pointer math, assembly code, and knowledge about the layout of the classes in memory to call private methods at runtime. This, however, is not very portable.
You could make the method public, but require that it take a parameter cryptographically signed by a private key which lives in the Window class, thus preventing other classes from being able to actually call the method and have it do anything.
You could make the method protected and make one inherit from the other.
You could make a common superclass which they both inherit from and use protected methods from it to communicate between them.
You could use the little used "enemy" keyword to allow them to run each other's private methods, but only when they have blackmail material which incriminates the other class. (Okay, that's not a real language feature, but it should be.)
Or you could just make them friends. That's much easier and saner than any of the other options and why friends exist.