Determine real type of base pointer in a big hierarchy without dynamic_cast - c++

Suppose, that I have an abstract base State class and at least two derived classes AnimalState and PlantState(also abstract). Also, I have many derived classes from AnimalState and PlantState.
class State{} // abstract
class AnimalState: public State{} // abstract
class PlantState: public State{} // abstract
//maybe few more of such classes here
class AnimalStateSpecific1: public AnimalState{}
class AnimalStateSpecific2: public AnimalState{}
... //many of them
class PlantStateSpecific1: public PlantState{}
class PlantStateSpecific2: public PlantState{}
... //many of them
Now suppose, that I use them in some kind of method that operates on base State pointers. Those pointers are replaced over time with other pointers to different class from the State hierarchy. It happens by some rule, specifically within the predefined state graph.
Now to the question part. In order to determine the next state, I need to know the previous one. But since I have only base State pointers, I can not efficiently tell what type of state I have, without doing dynamic_cast to every derived class in the hierarchy that is not good. I can have some enum with all kinds of states that I have, but I do not really like that because I do not want to mix information from two hierarchy branches, as it is really different. Also, I do not like different enums for every branch in the hierarchy such as AnimalStateEnum, PlantStateEnum etc.
What is the best solution for this problem? Maybe my design is not good from the start? I want to keep it as generic as possible and work only with base class objects, if possible.

Now to the question part. In order to determine the next state, I need to know the previous one.
Simplest solution based on limited information we have - object, which knows it's own state creates next state object:
class State{
public:
...
virtual std::unique_ptr<State> transform( some data ) = 0;
};
then you implement it in each derived from State class which can change it's state and knows where it can move to. What data you need to pass is not a simple question - it depends on your task and may have various options, but you need to define something that can be used by all derived classes, as signature is defined on the base class and shared on all derived ones.
What is the best solution for this problem? Maybe my design is not good from the start?
This question is not trivial and only can be answered having pretty deep knowledge on your task. If you are unsure - implement a prototype and check if solution fits your problem well. Unfortunately the only way to learn how to create a good design is your own experience (except trivial cases of course).

You could simply have a virtual method next() inside the state class hierarchy,
and then do something similar to the following example:
State *globalState = nullptr;
void foo(State *s)
{
globalState = s->next();
}
Where each derived class will implement next() to its own meaning:
PlantStateSpecific1 *AnimalStateSpecific1::next(){ return new PlantStateSpecific1; }
AnimalStateSpecific1 *PlantStateSpecific1::next(){ return new AnimalStateSpecific1; }
This is more OOP than having an enum / integer descriptor of the derived class.

What you can have is an integer inside the base state class that every class below it will set in its constructor. Then you can either use a sereis of constants, a list of possible states with the id corresponding to the state type index, or use an enumerator.
The id is more flexible as you can create state types with relative ease and add handling to them without too much difficulty, aswell as if you want to create a new state from the id type.
Just one of the ways iv done this before, but there are probably many others.

Related

Variable types from inherited classes

If I have a class that inherits from a base class, can I use that base class as a variable type in c++?
class Component {
// Code here
};
class TransformComponent : public Component {
// Code here
};
class Entity {
// Code here
Component *getComponent(Component *searchComponent) {
// Code Here
}
};
as you can see here, I am using the base class "Component" as a return type and a variable type. The problem is that the user may input a "TransformComponent". The only reason I am asking this is because the "TransformComponent" class inherits from the "Component" class and there might be a way to do this?
<Entity>.getComponent(Component &TransformComponent());
The answer I'm looking for is one that works both for the return type, and the variable type.
Absolutely! It's one of the beauties of OOP. Your instanced class of type TransformComponent is both an instance of Component as well as TransformComponent.
If you had some function that returned a type of Component, this could return any class derived from Component as a Component! If you later wanted to refer to it as its sub-class, you might have to check its type and then cast to it, but what you want is absolutely possible, and you're going the right way about it.
In fact, in the example you describe, were you are using Component and the user might pass a TransformComponent, all of the base methods and properties that the Component possesses will be possessed by TransformComponent too. It will look and feel as if it was a Component, with all the benefits of being one.
The only time a problem will arise is if you specifically want to access the features of a TransformComponent, and the user passed a Component. The parent class doesn't know about the sub-class stuff, because it isn't an instance of one, it will throw up errors for you. Sub-classes build upon the base class, so they have all the base-class stuff, plus more. Basically its only an issue when your example is reversed.
Your Entity.getComponent() method suggests that it only cares that the provided argument is a Component ... not any specialization, such as TransformComponent, of that original class.
So, if you find yourself writing logic that actually cares that "this Component might actually be a TransformComponent," then "warning bells should be going off." Create method definitions within the class that are as specific as possible.

C++ classes hierarchy design choice

In my simulation I have different objects that can be sensed in three ways: object can be seen and/or heard and/or smelled. For example, Animal can be seen, heard and smelled. And piece of Meat on the ground can be seen and smelled but not heard and Wall can only be seen. Then I have different sensors that gather this information - EyeSensor, EarSensor, NoseSensor.
Before state: brief version gist.github.com link
Before I started implementing NoseSensor I had all three functionality in one class that every object inherited - CanBeSensed because although classes were different they all needed the same getDistanceMethod() and if object implemented any CanBeSensed functionality it needed a senseMask - flags if object can be heard/seen/smelled and I didn't want to use virtual inheritance. I sacrificed having data members inside this class for smell, sounds, EyeInfo because objects that can only be seen do not need smell/sound info.
Objects then were registered in corresponding Sensor.
Now I've noticed that Smell and Sound sensors are the same and only differ in a single line inside a loop - one calls float getSound() and another float getSmell() on a CanBeSensed* object. When I create one of this two sensors I know what it needs to call, but I don't know how to choose that line without a condition and it's inside a tight loop and a virtual function.
So I've decided to make a single base class for these 3 functionality using virtual inheritance for base class with getDistanceMethod().
But now I had to make my SensorBase class a template class because of this method
virtual void sense(std::unordered_map<IdInt, CanBeSensed*>& objectsToSense) = 0;
, and it meant that I need to make SensorySubSystem class(manages sensors and objects in range) a template as well. And it meant that all my SubSystems like VisionSubSystem, HearingSubSystem and SmellSubSystem inherit from a template class, and it broke my SensorySystem class which was managing all SensorySubSystems through a vector of pointers to SensorySubSystem class std::vector<SensorySubSystem*> subSystems;
Please, could you suggest some solution for how to restructure this or how to make compiler decide at compile time(or at least decide once per call//once per object creation) what method to call inside Hearing/Smell Sensors.
Looking at your original design I have a few comments:
The class design in hierarchy.cpp looks quite ok to me.
Unless distance is something specific to sensory information getDistance() doesn't look like a method that belongs into this class. It could be moved either into a Vec2d-class or to a helper function (calculatePositon(vec2d, vec2d)). I do not see, why getDistance() is virtual, if it does something different than calculating the distance between the given position and the objects position, then it should be renamed.
The class CanBeSensed sounds more like a property and should probably be renamed to e.g. SensableObject.
Regarding your new approach:
Inheritance should primarily be used to express concepts (is-a-relations), not to share code. If you want to reuse an algorithm, consider writing an algorithm class or function (favour composition over inheritance).
In summary I propose to keep your original class design cleaning it up a little as described above. You could add virtual functions canBeSmelled/canBeHeard/canBeSeen to CanBeSensed.
Alternatively you could create a class hierachy:
class Object{ getPosition(); }
class ObjectWithSmell : virtual Object
class ObjectWithSound : virtual Object
...
But then you'd have to deal with virtual inheritance without any noticeable benefit.
The shared calculation code could go into an algorithmic class or function.

Is there any way to avoid declaring virtual methods when storing (children) pointers?

I have run into an annoying problem lately, and I am not satisfied with my own workaround: I have a program that maintains a vector of pointers to a base class, and I am storing there all kind of children object-pointers. Now, each child class has methods of their own, and the main program may or not may call these methods, depending on the type of object (note though that they all heavily use common methods of the base class, so this justify inheritance).
I have found useful to have an "object identifier" to check the class type (and then either call the method or not), which is already not very beautiful, but this is not the main inconvenience. The main inconvenience is that, if I want to actually be able to call a derived class method using the base class pointer (or even just store the pointer in the pointer array), then one need to declare the derived methods as virtual in the base class.
Make sense from the C++ coding point of view.. but this is not practical in my case (from the development point of view), because I am planning to create many different children classes in different files, perhaps made by different people, and I don't want to tweak/maintain the base class each time, to add virtual methods!
How to do this? Essentially, what I am asking (I guess) is how to implement something like Objective-C NSArrays - if you send a message to an object that does not implement the method, well, nothing happens.
regards
Instead of this:
// variant A: declare everything in the base class
void DoStuff_A(Base* b) {
if (b->TypeId() == DERIVED_1)
b->DoDerived1Stuff();
else if if (b->TypeId() == DERIVED_2)
b->DoDerived12Stuff();
}
or this:
// variant B: declare nothing in the base class
void DoStuff_B(Base* b) {
if (b->TypeId() == DERIVED_1)
(dynamic_cast<Derived1*>(b))->DoDerived1Stuff();
else if if (b->TypeId() == DERIVED_2)
(dynamic_cast<Derived2*>(b))->DoDerived12Stuff();
}
do this:
// variant C: declare the right thing in the base class
b->DoStuff();
Note there's a single virtual function in the base per stuff that has to be done.
If you find yourself in a situation where you are more comfortable with variants A or B then with variant C, stop and rethink your design. You are coupling components too tightly and in the end it will backfire.
I am planning to create many different children classes in different
files, perhaps made by different people, and I don't want to
tweak/maintain the base class each time, to add virtual methods!
You are OK with tweaking DoStuff each time a derived class is added, but tweaking Base is a no-no. May I ask why?
If your design does not fit in either A, B or C pattern, show what you have, for clairvoyance is a rare feat these days.
You can do what you describe in C++, but not using functions. It is, by the way, kind of horrible but I suppose there might be cases in which it's a legitimate approach.
First way of doing this:
Define a function with a signature something like boost::variant parseMessage(std::string, std::vector<boost::variant>); and perhaps a string of convenience functions with common signatures on the base class and include a message lookup table on the base class which takes functors. In each class constructor add its messages to the message table and the parseMessage function then parcels off each message to the right function on the class.
It's ugly and slow but it should work.
Second way of doing this:
Define the virtual functions further down the hierarchy so if you want to add int foo(bar*); you first add a class that defines it as virtual and then ensure every class that wants to define int foo(bar*); inherit from it. You can then use dynamic_cast to ensure that the pointer you are looking at inherits from this class before trying to call int foo(bar*);. Possible these interface adding classes could be pure virtual so they can be mixed in to various points using multiple inheritance, but that may have its own problems.
This is less flexible than the first way and requires the classes that implement a function to be linked to each other. Oh, and it's still ugly.
But mostly I suggest you try and write C++ code like C++ code not Objective-C code.
This can be solved by adding some sort of introspection capabilities and meta object system. This talk Metadata and reflection in C++ — Jeff Tucker demonstrates how to do this using c++'s template meta programming.
If you don't want to go to the trouble of implementing one yourself, then it would be easier to use an existing one such as Qt's meta object system. Note that this solution does not work with multiple inheritance due to limitations in the meta object compiler: QObject Multiple Inheritance.
With that installed, you can query for the presence of methods and call them. This is quite tedious to do by hand, so the easiest way to call such a methods is using the signal and slot mechanism.
There is also GObject which is quite simmilar and there are others.
If you are planning to create many different children classes in different files, perhaps made by different people, and also I would guess you don't want to change your main code for every child class. Then I think what you need to do in your base class is to define several (not to many) virtual functions (with empty implementation) BUT those functions should be used to mark a time in the logic where they are called like "AfterInseart" or "BeforeSorting", Etc.
Usually there are not to many places in the logic you wish a derived classes to perform there own logic.

Class design to avoid need for list of base classes

I'm currently in the design phase of a class library and stumbled up on a question similar to "Managing diverse classes with a central manager without RTTI" or "pattern to avoid dynamic_cast".
Imagine there is a class hierarchy with a base class Base and two classes DerivedA and DerivedB that are subclasses of Base. Somewhere in my library there will be a class that needs to hold lists of objects of both types DerivedA and DerivedB. Further suppose that this class will need to perform actions on both types depending on the type. Obviously I will use virtual functions here to implement this behavior. But what if I will need the managing class to give me all objects of type DerivedA?
Is this an indicator of a bad class design because I have the need to perform actions only on a subset of the class hierarchy?
Or does it just mean that my managing class should not use a list of Base but two lists - one for DerivedA and one for DerivedB? So in case I need to perform an action on both types I would have to iterate over two lists. In my case the probability that there will be a need to add new subclasses to the hierarchy is quite low and the current number is around 3 or 4 subclasses.
But what if I will need the managing class to give me all objects of
type DerivedA?
Is this an indicator of a bad class design because I have the need to
perform actions only on a subset of the class hierarchy?
More likely yes than no. If you often need to do this, then it makes sense to question whether the hierarchy makes sense. In that case, you should separate this into two unrelated lists.
Another possible approach is to also handle it through virtual methods, where e.g. DeriveB will have a no-op implementation for methods which don't affect that. It is hard to tell without knowing more information.
It certainly is a sign of bad design if you store (pointers to) objects together that have to be handled differently.
You could however just implement this differing behaviour as an empty function in the base class or use the visitor pattern.
You can do it in several ways.
Try to dynamic_cast to specific class (this is a bruteforce solution, but I'd use it only for interfaces, using it for classes is a kind of code smell. It'll work though.)
Do something like:
class BaseRequest {};
class DerivedASupportedRequest : public BaseRequest {};
Then modify your classes to support the method:
// (...)
void ProcessRequest(const BaseRequest & request);
Create a virtual method bool TryDoSth() in a base class; DerivedB will always return false, while DerivedA will implement the required functionality.
Alternative to above: Create method Supports(Action action), where Action is an enum defining possible actions or groups of actions; in such case calling DoSth() on class, which does not support given feature should result in thrown exception.
Base class may have a method ActionXController * GetControllerForX(); DerivedA will return the actual controller, DerivedB will return nullptr.
Similarly, base class can provide method: BaseController * GetController(Action a)
You asked, if it is a bad design. I believe, that it depends on how much functionality is common and how much is different. If you have 100 common methods and only one different, it would be weird to hold these data in separate lists. However, if count of different methods is noticeable, consider changing design of your application. This may be a general rule, but there are also exceptions. It's hard to tell without knowing the context.

How to: derived member in derived class with derived class specific methods

I am using C++ under Ubuntu 11.10 and the latest version of NetBeans. Let's say I have the
following code:
class Node {}
class DerivedNode : public Node {}
class Graph {
vector<Node*> nodes;
}
class DerivedGraph : public Graph { }
At the moment I'm storing DerivedNodes in the DerivedGraph class like this for example:
nodes.push_back(new DerivedNode());
When I need to use specific methods that only apply to DerivedNodes and DerivedGraphs
I am forced to use a dynamic_cast on my Node pointers first.
I would like to be able to have specific methods in DerivedGraph which apply only to DerivedNodes
and avoid the need of casting pointers. I do not mind having to redesign my classes if the end
result is better than what I have.
I am sure there must be a clean and simple method to achieve the same thing I'm trying to do.
Maybe something with specialized templates? Any thoughts on the matter would be greatly
appreciated. I'll also provide any additional information required in the case I haven't been too
clear.
EDIT: I don't have two copies. I wanted to put emphasis on how it looks. I apologize for the presentation. What I want to obtain is:
class DerivedGraph: public Graph {
vector<DerivedNode*> nodes;
}
Are you sure that your interface in Node is appropriate? Sometimes when you find yourself needing to downcast (especially in a case like this where base pointers are stored in a container) that may be a signal that your abstract interface doesn't cover all your needs properly. Often something like the Template Method pattern solves all your needs without needing a downcast at all.
However, assuming that your inheritance model really need work in such a way, what you probably want to do is have virtual methods that get overridden in DerivedGraph for adding and getting nodes. You will have to verify the node type and downcast it in this case.
One final approach is to have two separate containers, one in the parent that contains all nodes that aren't DerivedNode and then another container in DerivedGraph that contains all the DerivedNode. Then you use overridden functions again to determine which container to access depending on your API needs.
Start by not duplicating your data member in the derived class.
Then add virtual member functions that you use to add data to your container. That way you can create instances of derived types in the derived class and add them to the container.
Finally, when you override the virtual function that returns a reference to data in the derived class, use covariant return types.