I'm new to c++ and I have more of a "design" question than actual code:
I'd like to write a program that works with many different types of graphs, however I want to support any type of vertex or weight (i.e the vertices are strings or char and the weight can be int,double or char or even a class).
For this cause I wrote a class template of graphs, which contains things like a set of vertices and a map with the edges and their weights and get/set functions - Then I have other classes such as finite-state machine graph, a regular weighted graph etc. which inherit from the class template "Graphs". (in each graph I know exactly what types the vertices and weights will be)
I did this as it seemed natural to expand upon a base class and inherit from it. It works so far, but then I thought whats the point? I could simple create in each class one of these generic graphs and use it as I would use an ADT from the STL.
The point being, is there any benefit to inheriting from a class template instead of just creating a new object of the template in the class (which itself isn't generic)?
According to the explanation you gave above it would be incorrect to inherit the generic graph. Inheritance is a tool to help expand an existing class of the same type to one with additional attributes, methods and functionality.
So, if all you're going to do is take the generic graph and make it a specific one by specifying the type of edges and weights without adding anything else to the structure or functionality of the original class then inheritance is unnecessary.
That being said, there are many cases for which one might need to inherit a template class and either keep it a generic one or a specific one depending on the task at hand. For example, if you were given the task of creating a class that represents a list of integers with the regular operations on lists and in addition to implement a function that return (let's say the average of these numbers or any other operation that is not supported by the original generic class List). In this case you inherit Class List and add your method.
Similarly, you could've kept the List as a template class and added the required functionality if that's what the task requires.
Your question is very broad and highly depends on your particular situation. Regardless, assuming that your question can be simplified to: "why should I use inheritance when I can just put the object inside the class?", here are two objective reasons:
Empty base optimization: if your base class X is empty (i.e. sizeof(X) == 0), then storing it as one of your derived class's fields will waste some memory as the standard forces every field to have its own address. Using inheritance will prevent that. More information here.
Exposing public methods/fields to the user of the derived class: if you want to "propagate" all your base class's public methods/fields to the derived one, inheritance will do that automatically for you. If you use composition, you have to expose them manually.
Related
I am trying to design a class that would wrap shader parameter in such way that it would enable the user to easily set and get its value without a need to write a tonne of validation code outside of this class implementation.
The problem is that obviously the shader parameter values can be of different types, and whether I use templates or method overloading it results in a lot of messy code that if one was to use this class it would probably not be a very pleasant experience.
Is there some clever design pattern that once implemented would render the usage of said class to be more straightforward? I wouldn't mind if the mechanism was more complex as long as its implementation is not exposed to the user of this class.
Also just to be more clear, this shader parameter class is somewhat abstract in that its purpose is only to store the parameter for easier editing and handling across my code base. It does not interact or have any knowledge about the actual shader.
Edit 1:
Here's how I attempted to solve the issue before with templates and why I failed:
My template values were derived from a non template base class that I used to store them in a STL containers, but I have run into issues when retrieving the values and being unable to up cast them back into their template values, another issue was the amount of code needed to set and get the values when using this class implementation
Edit 2:
The ideal usage would be :
ShaderParameter* param = ShaderParameterCollection.GetParameter("color_param");
ShaderParameterCollection->GetParameter("property_name")->Set(vec3());
ShaderParameterCollection->GetParameter("property_name")->Get(&out);
ShaderParameterCollection->AddParameter("property_name", FLOAT_VEC3, vec3());
ShaderParamterCollection is just a storage class that internally uses STL container, does mapping and validation, I already have that one sorted.
What about a templated value class ? It's not a particular design pattern but could suit your needs pretty well by encapsulating :
1) your private shader data of different types and their public accessors
2) the validation code to be executed when the data are changing (coded in setters for example)
I would start by replacing the string property names that you currently have with typed keys, for example:
ShaderParameterKey<color> color_key("color_param");
ShaderParameterKey<vec3> property_key("property_name");
Then your collection methods could take a ShaderParameterKey<T> as input and return a ShaderParameter<T>. Your usage would look like:
ShaderParameter<color>* param = ShaderParameterCollection.GetParameter(color_key);
ShaderParameterCollection->GetParameter(property_key)->Set(vec3());
ShaderParameterCollection->GetParameter(property_key)->Get(&out);
ShaderParameterCollection->AddParameter(property_key, vec3());
You no longer need to pass the type (FLOAT_VEC3) to AddParameter because that is encoded in the key.
I'm not sure what issues you ran into in your previous attempt with the template base class but this solution calls for something similar.
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 it possible to derive a child from an array Class?
What I am playing with right now is:
Creating an array of Linked Lists
I am building a List class from which I can derive different types of lists (ie. Linear, Circular, Double Linked, etc...
What I would like to do is to extend an array class to make a "arrayOfLists" class. Then I would take the child class and add to it a LinkedList object member.
Is this possible? Am I even thinking of OOP correctly in this instance?
Thank you for your help
The fact that you're talking about it as an arrayOfLists class is a pretty good clue that inheritance is the wrong tool for this job.
Inheritance (public inheritance, anyway) should only be used when the derived class can be substituted for the base class under any possible circumstances. In other words, that an arrayOfLists could be used anywhere a List could be used. Although that might be possible, it seems fairly unlikely.
It sounds to me like what you want is really just an array-like template (e.g., std::vector) instantiated over one of your linked list classes.
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.
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.