Selecting the right strategy based on two object types - c++

I'm not sure how to name this problem, so I'm going to try to explain as good as I can.
I want to be able to switch strategies depending on the types of two different objects. To make this work, I am thinking of flagging the objects with an enum type, and having a 'registry' (arrayish) of these strategies. Ideally, the correct strategy would be accessed with some simple operation like a bitwise operator between the two types.
This pseudocode may make what I'm trying to explain easier to understand:
enum Type { A, B, C }
struct Object {
Type type;
}
class ActionRunner {
vector<Strategy> strategies;
void registerStrategy(type1, type2, strategy) {
strategies[type1 operator type2] = strategy;
}
void runStrategyFor(type1, type2) {
strategies[type1 operator type2].execute();
}
}
This would be easy to solve using a map, but I'd like to use an array or vector because a map seems like an overkill for a problem like this and using an array is probably much faster.
So the problem is I don't know what operator I might be able to use to select the 'position' of the right strategy. I've been thinking of a few combinations but it seems all of them end up causing collisions with the different combinations at some point.
Does anyone have any clues/advice on what I may be able to use for this?
PS: I know premature optimization is bad, but I'm just trying to figure out if this problem can be solved in a simple way.
------- EDIT ------------------------------------------------
In light of the answers, I've been giving the problem some extra thought and I've come to the conclusion what I intended with this question isn't possible the way I'd like it. I'm going to try to re-state the problem I'm trying to solve now using this question.
I'd like to have a class structure in which there's objects of certain type 'BaseClass' and a 'processor' object that takes two objects derived from 'BaseClass' and runs the right strategy for those. Something like this:
class Processor {
void run (DerivedA a, DerivedB b);
}
class BaseClass {}
class DerivedA: public BaseClass {}
class DerivedB: public BaseClass {}
BaseClass a = new DerivedA;
BaseClass b = new DerivedB;
processor.run(a, b)
According to what I understand, this would not work as I'd expect if what is passed as parameters to 'run' are references, which is what I'd rather do. Is there any way to do this without way-too-complicated code? (tripple dispatch!?)
I have in mind something like the double dispatch combined with an slave (processor) object that I think would work, but that seems awfully complex and probably a pain to maintain and extend.
Thanks!

The second sentence of your question rang a bell for me:
I want to be able to switch strategies depending on the types of two different objects.
This sounds like you want to perform a double dispatch. See the question (in particular, the answers to the question ;-)) at Double dispatch/multimethods in C++ for how to implement this in C++.

That's a classic example for using map instead of array. Array is actually a private case of map with key defined as an integer. In your case the key is a tuple so a simple array won't do and you'll end up with collisions (even if you're lucky for your specific input, your code will be extremely non-robust).
You can have an intermediate solution, between simple array and map: 2D array, with your 2 types serving as indices to rows and columns..

Related

Representing a game world, alternative to dynamic casting?

I'm trying to implement a game but first I need a way to represent the world that can hold players and items
I'm currently representing it as a 2D vector of <Entity> where Entity is a base class
Players and Items both derive from "Entity" class
Players and Items do not share common function except for maybe, a function that'll print their "information"
Dynamic casting will be needed, but I've read that it's a code smell as it is a school project, I wanna implement it in the "best way" possible
Any suggestions please ?
From the comments you've gotten so far, you can tell that at least some people think you should use separate arrays, and your argument for why it's one array doesn't really make sense, but sure...
The basic problem is that Items just flat out don't share a set of actions with Players, and the things you would do to each are different as well.
But if you insist on putting them into the same array, then you're going to need to detect what it is and end up with a typecast. Or do some polymorphism. For instance:
class Entity {
...
virtual void doSomeItemAction() {}
virtual void doSomePlayerAction() {}
}
class Item: public Entity {
...
void doSomeItemAction() override { ... }
}
et cetera.
Frankly, I wouldn't do it this way. I'd use separate vectors. But your two choices are detect type and typecast or do weird polymorphism that doesn't really fit your problem space, but you could make it work.

C++ Model View Design

I am currently struggling with the design of an application of the visualization and manipulation of sensor data. I have a database that contains several STL-containers with measured data in it.
std::unordered_map<std::string, std::array<uint16_t, 3366>> data1;
std::unordered_map<std::string, QImage> data2;
std::unordered_map<std::string, std::vector<Point3D>> data3;
I also have different Views (mostly Qt-based) and each view should be associated with a model which is specific to one of the data sets. So data1 is supposed to be processed and manipulated in a class called model1 which is then displayed by means of a class view1 and so forth.
But I cant seem to find a suitable design structure to incorporate this idea. the models grant access to their processed data, but that data is contained in different container structures as given above. That makes it unfeasible to use inheritance with a pure virtual function in the base class like
std::map<...,...> getModelData() = 0;
The initial idea of this inheritance was to avoid code duplication but that doesnt seem to be the right solution here. I know that Qt in their "Model-View" concepts makes use of their QVariant class to have maximum flexibility in terms of types being returned. However, I am wondering, what is the best solution with standard C++ here? I read a lot about striving for loose-coupling, code reuseability, Dependendy Inversion and how to favour composition over inheritance but I do have problems putting these theoretical advise into practice and end up with code bloat and repetitive code most of the times. Can you help me?
Maybe you can give more code but so far, I can give a few hints:
-Can you use QMap instead of std::unordered_map ? It is more agile if you need to tangle with a UI
-Maybe make your second argument of the list a common base type like (code not tested, treat as pseudo code)
class BaseDataClass
{
public:
int getType();
QImage* getImageData();
std::array<uint16_t, 3366>>& getArray();
std::vector<Point3D>>& getVector();
private:
int mType;
BaseDataClass(); //hide ctor or make abstract, as you wish
}
You can avoid code duplicating with this. Make three new classes that each inherit from BaseDataClass. You can then make a method that iterates over all BaseDataClass, checks the type (e.g. 1=QImage; 2 = array ; 3 = vector), and exectues the right method according to the type (get QImage from all type 1`s ...). You also can cast the pointer to the right type then. Which makes it even better if your derived classes gain more and more functionality (like sorting or validating data)

Store any value and a value of a specific range of classes

I have a class that looks something like this:
class container{
private:
std::vector<physical_component> physical;
std::vector<storage_component> storage;
--some other stuff not relevant--
public:
--constructors, getters setters, methods to add to the vectors etc--
}
Now I am struggeling with making the physical_component and storage_component classes since I dont know a proper datatype to handle this sort of thing.
Physical_component should be able to:
Store a set amount of types, and fully retaining a type (something I can cast to is good enough)
Should store the objects in a way that makes them individual from the ones passed (and therefore secure from changes to the orignial class)
I remember something like that excisting in c alongside enum but I dont know the name. Also c++ probably has a better way for that.
Storage_component is supposed to:
Store any type
(optional) remember the original type
I have no idea how to achieve this properly. I saw std::any but it seems to be rather new therefore I dont know if its a good way to go about this. Also I cant make storage_component a template because I cant store it in a vector then
What is the (proper) way to implement these classes?
Store a set amount of types, and fully retaining a type
You probably want std::variant<Ts...> (or boost::variant<Ts...>). It stores one of Ts... at a particular point in time.
Store any type
If all the types share the same interface, use a traditional virtual + std::unique_ptr polymorphism approach. Otherwise std::any is the right choice here.

How to structure a large routine when subtasks have strong interdependence

Dear StackOverflow :)
I am trying to implement a sort of pattern matching routine, that maps tree structures onto other tree structures in a specific way. Unfortunately the routine has to be very flexible, so that this operation is very non-trivial.
I can intuitively divide this large amount of work into smaller portions that can be handled sequentially, but I am having trouble to bring structure into the code I write. These subtasks have a very strong interdependence, so that if I break up the large function into smaller ones I need very much state information to get things right. This adds a lot of extra code and makes things hard to oversee - and, I am afraid, might reduce compiler optimization.
If I however choose to implement everything into a single large function, I am having problems with the "program flow" - I have to use a lot of goto statements (which I can mask away into something more pretty, but the problem still remains).
Now in general: How do you attack such problems that are "large"? Can you give me some hints about what I could look into?
Answering for C++, but the principles should be transferable.
I'd say the solution here is to realise that C++ objects don't have to correspond to "tangible" things. Why not represent the matching task as a class instead of a function?
Basically, create a noncopyable class with a public "driver" function. The subtasks (smaller portions) can be represented as non-public member functions of that class, and they can share data via the class's data members.
Something like this:
bool patternsMatch(Pattern a, Pattern b) {
return PatternMatcher(a, b).match();
}
class PatternMatcher
{
public:
PatternMatcher(Pattern a, Pattern b);
bool match() {
subtask1();
subtask2();
return res;
}
private:
bool res;
Pattern a, b;
int something_subtasks_share;
float more_shared_data;
void subtask1();
void subtask2();
};

Changing behavior of an object at runtime

How can be changed the behavior of an object at runtime? (using C++)
I will give a simple example. I have a class Operator that contains a method operate. Let’s suppose it looks like this:
double operate(double a, double b){
return 0.0;
}
The user will give some input values for a and b, and will choose what operation to perform let’s say that he can choose to compute addition or multiplication. Given it’s input all I am allowed to do is instantiate Operator and call operate(a, b), which is written exactly how I mentioned before.
The methods that compute multiplication or addition will be implemented somewhere (no idea where).
In conclusion I have to change the behavior of my Operator object depending on the user's input.
The standard pattern for this is to make the outer class have a pointer to an "implementation" class.
// derive multiple implementations from this:
class Implementation
{
virtual ~Implementation() {} // probably essential!
virtual void foo() = 0;
};
class Switcheroo
{
Implementation *impl_;
public:
// constructor, destructor, copy constructor, assignment
// must all be properly defined (any that you can't define,
// make private)
void foo()
{
impl_->foo();
}
};
By forwarding all the member functions of Switcheroo to the impl_ member, you get the ability to switch in a different implementation whenever you need to.
There are various names for this pattern: Pimpl (short for "private implementation"), Smart Reference (as opposed to Smart Pointer, due to the fowarding member functions), and it has something in common with the Proxy and Bridge patterns.
I'm mentioning this only as trivia and can't unrecommend it more, but here we go...
WARNING DANGER!!!
A stupid trick I've seen is called clutching, I think, but it's only for the truely foolish. Basically you swap the virtualtable pointer to that of another class, it works, but it could theoretically destroy the world or cause some other undefined behavior :)
Anyways instead of this just use dynamic classing and kosher C++, but as an experiment the above is kind of fun...
Coplien's Envelope/Letter Pattern (in his must read book Advanced C++ Programming Styles and Idioms) is the classic way to do this.
Briefly, an Envelope and a Letter are both subclasses of an abstract base class/interfcae that defines the public interface for all subclasses.
An Envelope holds (and hides the true type of) a Letter.
A variety of Letter classes have different implementations of the abstract class's public interface.
An Envelope has no real implementation; it just forards (delegates) to its Letter. It holds a pointer to the abstract base class, and points that at a concrete Letter class instance. As the implementation needs to be changed, the type of Letter subclass pointer to is changed.
As users only have a reference to the Envelope, this change is invisible to them except in that the Envelope's behavior changes.
Coplien's examples are particularly clean, because it's the Letters, not the envelope that cause the change.
One example is of a Number class hierarchy. The abstract base declares certain operations over all Numbers, e.g, addition. Integer and a Complex are examples of concrete subclasses.
Adding an Integer and an Integer results in an Integer, but adding a Interget and a Complex results in a Complex.
Here's what the Envelope looks like for addition:
public class Number {
Number* add( const Number* const n ) ; // abstract, deriveds override
}
public class Envelope : public Number {
private Number* letter;
...
Number* add( const Number& rhs) { // add a number to this
// if letter and rhs are both Integers, letter->add returns an Integer
// if letter is a a Complex, or rhs is, what comes back is a Complex
//
letter = letter->add( rhs ) ) ;
return this;
}
}
Now in the client's pointer never changes, and they never ever need to know what the Envelop is holding. Here's the client code:
int main() {
// makeInteger news up the Envelope, and returns a pointer to it
Number* i = makeInteger( 1 ) ;
// makeComplex is similar, both return Envelopes.
Number* c = makeComplex( 1, 1 ) ;
// add c to i
i->add(c) ;
// to this code, i is now, for all intents and purposes, a Complex!
// even though i still points to the same Envelope, because
// the envelope internally points to a Complex.
}
In his book, Coplien goes into greater depth -- you'll note that the add method requires multi-dispatch of some form --, and adds syntactic sugar. But this is the gist of how you can get what's called "runtime polymorphism".
You can achieve it through dynamic binding (polymorphism)... but it all depends on what you are actually trying to achieve.
You can't change the behavior of arbitrary objects using any sane way unless the object was intended to use 'plugin' behaviour through some technique (composition, callbacks etc).
(Insane ways might be overwriting process memory where the function code lies...)
However, you can overwrite an object's behavior that lies in virtual methods by overwriting the vtable (An approach can be found in this article ) without overwriting memory in executable pages. But this still is not a very sane way to do it and it bears multiple security risks.
The safest thing to do is to change the behavior of objects that were designed to be changed by providing the appropriate hooks (callbacks, composition ...).
Objects always have the behaviour that's defined by their class.
If you need different behaviour, you need a different class...
You could also consider the Role Pattern with dynamic binding..i'm struggling with the same thing that you do..I read about the Strategy pattern but the role one sounds like a good solution also...
There are many ways to do this proxying, pImpl idiom, polymorphism, all with pros and cons. The solution that is best for you will depend on exactly which problem you are trying to solve.
Many many ways:
Try if at first. You can always change the behavior with if statement. Then you probably find the 'polymorphism' way more accurate, but it depends on your task.
Create a abstract class, declaring the methods, which behavior must be variable, as virtual.
Create concrete classes, that will implement the virtual methods. There are many ways to achieve this, using design patterns.
You can change the object behavior using dynamic binding. The design patterns like Decorator, Strategy would actually help you to realize the same.