A proper way to restrict access to an interface? - c++

Let's say I have a class that represents a printing job: CPrintingJob. It knows nothing of the document being printed, just the job state - whether the job was queued, rejected, carried on etc.
The idea is an object of this class is instantiated whenever some printing needs to be done, then passed to the printing module along with other data, then the job's creator checks its state to see how printing is going.
Suppose CPrintingJob inherits two interfaces:
class IPrintingJob // this one is to check the job state
{
virtual TState GetState() const = 0;
// ... some other state-inquiring methods
class ICallback // job's owner is notified of state changes via this one
{
virtual void OnStateChange( const IPrintingJob& Job ) = 0;
};
};
and
class IPrintingJobControl // this one is for printing module to update the state
{
virtual void SetState( const TState& NewState ) = 0;
// ... some other state-changing methods
};
Problem is, the class that creates a CPrintingJob object shouldn't have access to the IPrintingJobControl, but the printing module CPrintingJob is being passed to must be able to change its state and, therefore, have access to that interface.
I suppose this is exactly the case where friends should be used but I have always avoided them as an inherently flawed mechanic and consequently have no idea of how to use them properly.
So, how do I do it properly?

Use a factory and have the factory return an instance of IPrintingJob (best wrapped inside a smart_ptr). e.g.:
struct PrintingFactory {
static auto create() -> std::unique_ptr<IPrintingJob> {
return std::unique_ptr<IPrintingJob>(new CPrintingJob());//as there is currently no std::make_unique..
}
}
Once you have to use the JobControl you can simply cast the pointer via std::dynamic_pointer_cast.

After some deliberation I've decided that:
This whole thing is definitely more trouble than it's worth;
(A slightly modified) version of MFH's answer above is the only, hence the best, way to go.
Thanks everyone for the input, it certainly has been enlightening.

Related

Two versions of the program depending on the input parameter without code duplication

I am solving the following problem. I am working on an optimization program in C ++ which, depending on the initial settings of the user, uses various regulations (standards) to calculate the target function. Suppose we have a method A based on some norm and a method B based on another norm to calculate the target function. The user is setting the right standard before starting the program. The rest of the code is the same. During optimization, the target function is iteratively called over and over again. Of course, there is a simple solution: each time the target function is called, the IF condition is used to decide which standard to use. But because the program has to make decisions in every iteration, it seems to be ineffective. The second option is to create 2 independent codes and run only the one with the required standard. This, in turn, is ugly in terms of duplicate code.
I imagined that I would create 2 different classes and use the selected class using the IF condition when constructing the object. This would make the program decide only once when creating the object, but during the iteration itself the object would be clearly defined. Unfortunately, this does not work because objects cannot be created in IF conditions.
//-----------------------------------------------------------
// Create object sensor based on input
if(data.sensors_tipe == "Uniaxial_025") Sensor_Uniaxial_025 sensor(data);
else if (data.sensors_tipe == "T_rosette_05") Sensor_T_rosette_05 sensor(data);
else report.error("some error");
// rotation test
int element_index = 1;
double orientation_angle = 3.490658503988659;
sensor.rotate(element_index, orientation_angle);
Another way I would like is to set the correct method using a parameter in the constructor. Unfortunately, that probably isn't possible either.
I am a beginner and I did not find the answer anywhere. So maybe someone can help. Thanks
This is a good job for templates, which are "recipes" to generate code.
The end result will be duplicated machine code, but without the duplication in the source.
template<typename MethodT>
float optimize(const MethodT& method) {
float v = method();
// etc...
}
float methodA();
float methodB();
int main() {
auto a = optimize(methodA);
auto b = optimize(methodB);
}
First, the solution with if may be not that bad. It is branch on each function call, but the branch should be predicted well.
Second, if the functions that implement method A and method B are large enough to miss inlining, use function pointer.
Otherwise, use static polymorphism with templates, method A and method B may be passed via template parameter as functors.
In case, the user can change standard after programm compilation (for example, before each run) you can create interface and 2 child from it.
So, at startup you should create the instance (one of 2) you need through new. And then you can use it.
You can't use that algorithm with stack instances.
One way is to use inheritance.
class Sensor
{
public:
virtual void rotate(int, double) = 0;
};
class Sensor_Uniaxial_025 : public Sensor
{
public:
virtual void rotate(int, double) {/*stuff*/};
};
class Sensor_T_rosette_05 : public Sensor
{
public:
virtual void rotate(int, double) {/*stuff*/};
};
Sensor* sensorToUse;
//-----------------------------------------------------------
// Create object sensor based on input
if(data.sensors_tipe == "Uniaxial_025") sensorToUse = new Sensor_Uniaxial_025(data);
else if (data.sensors_tipe == "T_rosette_05") sensorToUse = new
Sensor_T_rosette_05(data);
else report.error("some error");
// rotation test
int element_index = 1;
double orientation_angle = 3.490658503988659;
sensorToUse->rotate(element_index, orientation_angle);
The example above, with new, comes with serious memory management issues. But if you pre-allocate the sensor for each type, in a single instance, and use a look-up instead it works well.
The alternative is with template. See other answers for these approaches.

c++ particle system inheritance

i'm creating particle system and i want to have possibility to choose what kind of object will be showing on the screen (like simply pixels, or circle shapes). I have one class in which all parameters are stored (ParticleSettings), but without those entities that stores points, or circle shapes, etc. I thought that i may create pure virtual class (ParticlesInterface) as a base class, and its derived classes like ParticlesVertex, or ParticlesCircles for storing those drawable objects. It is something like that:
class ParticlesInterface
{
protected:
std::vector<ParticleSettings> m_particleAttributes;
public:
ParticlesInterface(long int amount = 100, sf::Vector2f position = { 0.0,0.0 });
const std::vector<ParticleSettings>& getParticleAttributes() { return m_particleAttributes; }
...
}
and :
class ParticlesVertex : public ParticlesInterface
{
private:
std::vector<sf::Vertex> m_particleVertex;
public:
ParticlesVertex(long int amount = 100, sf::Vector2f position = { 0.0,0.0 });
std::vector<sf::Vertex>& getParticleVertex() { return m_particleVertex; }
...
}
So... I know that i do not have access to getParticleVertex() method by using polimorphism. And I really want to have that access. I want to ask if there is any better solution for that. I have really bad times with decide how to connect all that together. I mean i was thinking also about using template classes but i need it to be dynamic binding not static. I thought that this idea of polimorphism will be okay, but i'm really need to have access to that method in that option. Can you please help me how it should be done? I want to know what is the best approach here, and also if there is any good answer to that problem i have if i decide to make that this way that i show you above.
From the sounds of it, the ParticlesInterface abstract class doesn't just have a virtual getParticleVertex because that doesn't make sense in general, only for the specific type ParticlesVertex, or maybe a group of related types.
The recommended approach here is: Any time you need code that does different things depending on the actual concrete type, make those "different things" a virtual function in the interface.
So starting from:
void GraphicsDriver::drawUpdate(ParticlesInterface &particles) {
if (auto* vparticles = dynamic_cast<ParticlesVertex*>(&particles)) {
for (sf::Vertex v : vparticles->getParticleVertex()) {
draw_one_vertex(v, getCanvas());
}
} else if (auto* cparticles = dynamic_cast<ParticlesCircle*>(&particles)) {
for (CircleWidget& c : cparticles->getParticleCircles()) {
draw_one_circle(c, getCanvas());
}
}
// else ... ?
}
(CircleWidget is made up. I'm not familiar with sf, but that's not the point here.)
Since getParticleVertex doesn't make sense for every kind of ParticleInterface, any code that would use it from the interface will necessarily have some sort of if-like check, and a dynamic_cast to get the actual data. The drawUpdate above also isn't extensible if more types are ever needed. Even if there's a generic else which "should" handle everything else, the fact one type needed something custom hints that some other future type or a change to an existing type might want its own custom behavior at that point too. Instead, change from a thing code does with the interface to a thing the interface can be asked to do:
class ParticlesInterface {
// ...
public:
virtual void drawUpdate(CanvasWidget& canvas) = 0;
// ...
};
class ParticlesVertex {
// ...
void drawUpdate(CanvasWidget& canvas) override;
// ...
};
class ParticlesCircle {
// ...
void drawUpdate(CanvasWidget& canvas) override;
// ...
};
Now the particles classes are more "alive" - they actively do things, rather than just being acted on.
For another example, say you find ParticlesCircle, but not ParticlesVertex, needs to make some member data updates whenever the coordinates are changed. You could add a virtual void coordChangeCB() {} to ParticlesInterface and call it after each motion model tick or whenever. With the {} empty definition in the interface class, any class like ParticlesVertex that doesn't care about that callback doesn't need to override it.
Do try to keep the interface's virtual functions simple in intent, following the Single Responsibility Principle. If you can't write in a sentence or two what the purpose or expected behavior of the function is in general, it might be too complicated, and maybe it could more easily be thought of in smaller steps. Or if you find the virtual overrides in multiple classes have similar patterns, maybe some smaller pieces within those implementations could be meaningful virtual functions; and the larger function might or might not stay virtual, depending on whether what remains can be considered really universal for the interface.
(Programming best practices are advice, backed by good reasons, but not absolute laws: I'm not going to say "NEVER use dynamic_cast". Sometimes for various reasons it can make sense to break the rules.)

C++ design choice

There is a class ActionSelection which has the following method:
ActionBase* SelectAction(Table* table, State* state);
ActionBase is an abstract class. Inside of the SelectAction method some action is fetched from the table considering the state if the table is not empty.
If the table is empty, a random action should be created and returned. However ActionBase is an abstract class, so can not be instantiated.
For different experiments/environments actions are different but have some common behavior (that's why there is an ActionBase class)
The problem is that this function (SelectAction) should return an experiment specific action, if the table is empty, however it does not know anything about the specific experiment. Are there any design workarounds of this?
It depends on whether empty tables...
Are expected to happen under normal circumstances
May happen under abnormal circumstances
Should never happen unless there is a bug in the program
Solution 1:
Include empty table handling into your control flow. As-is the function does not have enough information to react properly, so either :
Pass in a third parameter, containing a default action to return :
ActionBase *SelectAction(Table *table, State *state, ActionBase *defaultAction);
If you don't want to construct the default action unless it's needed, you can pass its type via a template parameter instead, optionally with additional parameters to construct it with :
template <class DefaultAction, class... DefActArgs>
ActionBase *SelectAction(Table *table, State *state, DefActArgs &&... args);
Let the caller handle it, by returning whether or not the operation was successful :
bool SelectAction(Table *table, State *state, ActionBase *&selectedAction);
Solution 2:
Throw an exception. It will bubble up to whoever can handle it. This is quite rarely used as a parameter check, since it should have been thrown by the object that should have produced a non-empty table in the first place.
ActionBase *SelectAction(Table *table, State *state) {
if(table->empty())
throw EmptyTableException();
// ...
}
Solution 3:
Setup an assertion. If your function received an empty table, something is broken, better halt the program and have a look at it with a debugger.
ActionBase *SelectAction(Table *table, State *state) {
assert(!table->empty());
// ...
}
Here is what I had in mind : It is not tested code but you get the idea.
1.
//header
class RandomActionBase : public ActionBase{
public
RandomActionBase();
static RandomAction* selectRandomAction();
protected:
static RandomActionBase* _first;
RandomActionBase* _next;
void register(RandomActionBase* r);
};
//implementation
RandomActionBase::_first = NULL;
RandomActionBase::RandomActionBase():_next(NULL){
if (_first==NULL) _first = this;
else _first->register(this);
}
void RandomActionBase::register(RandomActionBase* r)
{
if (_next==NULL) _next = r;
else _next->register(r);
}
RandomAction* RandomActionBase::selectRandomAction()
{
//count the number of randomactionbases
int count = 0;
RandomActionBase* p = _first;
while(p){
++count;
p = p->_next;
}
//now that you know the count you can create a random number ranging from 0 to count, I 'll leave this up to you and assume the random number is simply 2,
unsigned int randomnbr = 2;
RandomActionBase* p = _first;
while(randomnbr>0){
p= p->_next;
--randomnbr;
}
return p;
}
//header
class SomeRandomAction : public RandomActionBase{
public:
//implement the custom somerandomaction
}
//implementation
static SomeRandomAction SomeRandomAction_l;
The idea of course is to create different implementations of SomeRandomAction or even to pass parameters to them via their constructor to make them all distinct. For each instance you create they will appear in the static list.
Extending the list with a new imlementation just means to derive from RandomActionBase , implement it and make sure to create an instance, the base class is never impacted by this which make it even a design according to OCP.
Open closed principle. The code is extendable while not having to change the code that is already in place. OCP is part of SOLID.
2.
Another viable solution is to return a null object. It is quite similar as above but you always return the null object when the list is empty. Mind you a null object is not simply null. See https://en.wikipedia.org/wiki/Null_Object_pattern
It is simply a dummy implementation of a class to avoid having to check for null pointers to make the design more elegant and less susceptible for null pointer dereferencing errors.

Boost.Python: Grab 'self' from member function

Class member functions in Python have to explicitly declare a self parameter which represents the class instance. Is there a way to get a hold of self from C++, by using Boost?
class FooBar
{
public:
void func() {
}
};
// A wrapper for the above class
struct FooBar_W
: public FooBar
{
void func(boost::python::object self) {
// Do smth with `self`
FooBar::func();
}
};
BOOST_PYTHON_WRAPPER(module)
{
class_<FooBar_W>("FooBar")
.def("func", &FooBar_W::func)
;
}
Edit: Why I want self
I'm writing an event system for my game and I want the scripter to be able to define new types of events. I need a way to distinguish between different types of events. My Python code looks something like this:
class KeyboardEvent(Event):
pass
def onKeyPress(event):
pass
# EventManager is defined in C++
em = EventManager()
# This is how I register a new callback function with the manager
# The `onKeyPress` function will now only be notified when an event
# of type `KeyboardEvent` occurs. (Notice that I passed the actual
# class object, and not an instance of it.)
em.addEventHandler(KeyboardEvent, onKeyPress)
# This is how I queue new events
# (This time I pass an instance of an event, not a type of event.)
em.queueEvent(KeyboardEvent())
The manager needs to figure out what type of event I just queued. I figured I should do something like type(event).__name__ (but in C++, not in Python). This way I can determine the type and know which functions to notify of the event. I want to get self in C++ so I can access the __name__ attribute of its type.
I could have the scripter manually edit a new field that holds the name of the type, but why? That information already exists (the __name__ attribute) so why duplicate it, but more importantly, why bother the scripter with implementation details?
It's doable. The way to do it can be found in the link below; that page documents one way (the old way) to expose pure virtual functions. The example can be adapted to other needs, though.
> http://wiki.python.org/moin/boost.python/OverridableVirtualFunctions#Pure_Virtual_Functions
it's an old question, but for those who are still looking for a reasonably simple solution:
Static function (non-member as well as member) receive a const boost::python::object& self as the first argument. So you can do the following:
class FooBar
{
public:
static void func(const boost::python::object self) {
FooBar& thisref = boost::python::extract<FooBar&>(self)();
// use self as well as thisref
}
};
};
BOOST_PYTHON_WRAPPER(module)
{
class_<FooBar>("FooBar")
.def("func", &FooBar::func)
;
}
self in python is this in C++.
You can think of the line FooBar::func(); as translating to static_cast<FooBar*>(this)->func()

Reconciling classes, inheritance, and C callbacks

In my C++ project, I've chosen to use a C library. In my zeal to have a well-abstracted and simple design, I've ended up doing a bit of a kludge. Part of my design requirement is that I can easily support multiple APIs and libraries for a given task (due, primarily, to my requirement for cross-platform support). So, I chose to create an abstract base class which would uniformly handle a given selection of libraries.
Consider this simplification of my design:
class BaseClass
{
public:
BaseClass() {}
~BaseClass() {}
bool init() { return doInit(); }
bool run() { return doWork(); }
void shutdown() { destroy(); }
private:
virtual bool doInit() = 0;
virtual bool doWork() = 0;
virtual void destroy() = 0;
};
And a class that inherits from it:
class LibrarySupportClass : public BaseClass
{
public:
LibrarySupportClass()
: BaseClass(), state_manager(new SomeOtherClass()) {}
int callbackA(int a, int b);
private:
virtual bool doInit();
virtual bool doWork();
virtual void destroy();
SomeOtherClass* state_manager;
};
// LSC.cpp:
bool LibrarySupportClass::doInit()
{
if (!libraryInit()) return false;
// the issue is that I can't do this:
libraryCallbackA(&LibrarySupportClass::callbackA);
return true;
}
// ... and so on
The problem I've run into is that because this is a C library, I'm required to provide a C-compatible callback of the form int (*)(int, int), but the library doesn't support an extra userdata pointer for these callbacks. I would prefer doing all of these callbacks within the class because the class carries a state object.
What I ended up doing is...
static LibrarySupportClass* _inst_ptr = NULL;
static int callbackADispatch(int a, int b)
{
_inst_ptr->callbackA(a, b);
}
bool LibrarySupportClass::doInit()
{
_inst_ptr = this;
if (!libraryInit()) return false;
// the issue is that I can't do this:
libraryCallbackA(&callbackADispatch);
return true;
}
This will clearly do Bad Things(TM) if LibrarySupportClass is instantiated more than once, so I considered using the singleton design, but for this one reason, I can't justify that choice.
Is there a better way?
You can justify that choice: your justification is that the C library only supports one callback instance.
Singletons scare me: It's not clear how to correctly destroy a singleton, and inheritance just complicates matters. I'll take another look at this approach.
Here's how I'd do it.
LibrarySupportClass.h
class LibrarySupportClass : public BaseClass
{
public:
LibrarySupportClass();
~LibrarySupportClass();
static int static_callbackA(int a, int b);
int callbackA(int a, int b);
private:
//copy and assignment are rivate and not implemented
LibrarySupportClass(const LibrarySupportClass&);
LibrarySupportClass& operator=(const LibrarySupportClass&);
private:
static LibrarySupportClass* singleton_instance;
};
LibrarySupportClass.cpp
LibrarySupportClass* LibrarySupportClass::singleton_instance = 0;
int LibrarySupportClass::static_callbackA(int a, int b)
{
if (!singleton_instance)
{
WHAT? unexpected callback while no instance exists
}
else
{
return singleton_instance->callback(a, b);
}
}
LibrarySupportClass::LibrarySupportClass()
{
if (singleton_instance)
{
WHAT? unexpected creation of a second concurrent instance
throw some kind of exception here
}
singleton_instance = this;
}
LibrarySupportClass::~LibrarySupportClass()
{
singleton_instance = 0;
}
My point is that you don't need to give it the external interface of a canonical 'singleton' (which e.g. makes it difficult to destroy).
Instead, the fact that there is only one of it can be a private implementation detail, and enforced by a private implementation detail (e.g. by the throw statement in the constructor) ... assuming that the application code is already such that it will not try to create more than one instance of this class.
Having an API like this (instead of the more canonical 'singleton' API) means that you can for example create an instance of this class on the stack if you want to (provided you don't try to create more than one of it).
The external constraint of the c library dictates that when your callback is called you don't have the identification of the "owning" instance of the callback. Therefore I think that your approach is correct.
I would suggest to declare the callbackDispatch method a static member of the class, and make the class itself a singleton (there are lots of examples of how to implement a singleton). This will let you implement similar classes for other libraries.
Dani beat me to the answer, but one other idea is that you could have a messaging system where the call back function dispatch the results to all or some of the instances of your class. If there isn't a clean way to figure out which instance is supposed to get the results, then just let the ones that don't need it ignore the results.
Of course this has the problem of performance if you have a lot of instances, and you have to iterate through the entire list.
The problem the way I see it is that because your method is not static, you can very easily end up having an internal state in a function that isn't supposed to have one, which, because there's a single instance on the top of the file, can be carried over between invocations, which is a -really- bad thing (tm). At the very least, as Dani suggested above, whatever methods you're calling from inside your C callback would have to be static so that you guarantee no residual state is left from an invocation of your callback.
The above assumes you have static LibrarySupportClass* _inst_ptr declared at the very top. As an alternative, consider having a factory function which will create working copies of your LibrarySupportClass on demand from a pool. These copies can then return to the pool after you're done with them and be recycled, so that you don't go around creating an instance every time you need that functionality.
This way you can have your objects keep state during a single callback invocation, since there's going to be a clear point where your instance is released and gets a green light to be reused. You will also be in a much better position for a multi-threaded environment, in which case each thread gets its own LibrarySupportClass instance.
The problem I've run into is that because this is a C library, I'm required to provide a C-compatible callback of the form int (*)(int, int), but the library doesn't support an extra userdata pointer for these callbacks
Can you elaborate? Is choosing a callback type based on userdata a problem?
Could your callback choose an instance based on a and/or b? If so, then register your library support classes in a global/static map and then have callbackADispatch() look up the correct instance in the map.
Serializing access to the map with a mutex would be a reasonable way to make this thread-safe, but beware: if the library holds any locks when it invokes your callback, then you may have to do something more clever to avoid deadlocks, depending on your lock hierarchy.