How can I manage a group of derived but otherwise Unrelated Classes - c++

It seems the more I talk about this problem the better I understand it. I think my previous question didn't convey what I am trying to do correctly. My apologies for that.
In my design I have GameObjects which are essentially an aggregation class, all functionality in a GameObject is implemented by adding various "Features" to it. A Feature is a Subclass of the Feature class that has it's own members and functions. All Features can receive Messages
class Feature
{
public:
virtual void takeMessage(Message& message) = 0;
};
class VisualFeature : public Feature
{
public:
void takeMessage(Message& message);
private:
RenderContext m_renderer;
};
... Additional Features ...
FeatureServers are objects that are responsible for coordinating the various Features. GameObjects can subscribe to FeatureServers to receive messages from them, and Features can Subscribe to GameObjects to handle the messages it is interested in.
So for example in this code:
GameObject Square;
VisualFeature* SquareSprite = new VisualFeature();
Square.subscribe(SquareSprite, "MESSAGE_RENDER");
Square.addFeature(SquareSprite);
m_VisualFeatureServer.subscribe(Square, "MESSAGE_RENDER");
The VisualFeatureServer sends the message tied to "MESSAGE_RENDER" which may look something like this
class Message
{
public:
std::string getID() {return m_id;}
bool isConsumed() {return m_consumed;}
void consume() {m_consumed = true;}
protected:
bool isConsumed;
std::string m_id;
}
class Message_Render : public Message
{
public:
Message_Render() : m_id("MESSAGE_RENDER"), m_consumed(false) {}
RenderTarget& getRenderTarget() {return m_target;}
private:
RenderTarget& m_target;
};
When the VisualFeatureServer sends the Message_Render class to the Square GameObject it then forwards it to any FeatureComponents that are subscribed to receive that particular message. In this case the VisualFeature class receives the Message_Render message. Here is where my problem is, the VisualFeature class is going to receive a Message& that it can tell is a Message_Render by it's ID, I want to be able to treat it as a Message_Render rather then a Message like so:
void VisualFeature::takeMessage(Message& message)
{
//Here's the problem, I need a pattern to handle this elegantly
derivedMessage = convertMessageToDerivedType(message);
this->handleDerivedMessageType(derivedMessage);
}
void VisualFeature::handleDerivedMessageType(Message_Render& message)
{
message.getRenderTarget().render(m_renderer);
message.consume();
}
Is there a way to elegantly deal with the takeMessage portion of this design?

The other answer was getting too bloated with edits, so I started a new one.
The casting you are doing in the receiveMessage() functions is definitely a code smell.
I think you need to use a combination of:
Abstract factory pattern to instantiate your objects (messages and components)
Observer pattern to respond to messages
The idea is that each component type will only subscribe to messages of its own type, and will therefore only receive messages intended for it. This should eliminate the need for casting.
The notifying object could, as an example, use a vector of notifier objects indexed by the message ID. The observing object (the derived component class) could subscribe to the particular notifier indexed by its own message ID.
Do you think this design pattern would help?

I'm not sure that I really understand your question, and I think you need to clarify what you are trying to achieve more.
Just a few other comments though.
I don't think public inheritance (as you have implemented) is the best design pattern to use here. The golden rule with public inheritance is that it should only be used if the derived class truly "is a" object of the base class.
One of the main benefits of using inheritance in C++ is to implement polymorphism where (for example) you have a list of pointers to Base objects and you invoke methods on those objects, and they are dispatched to the relevant VisualComponent and PhysicsComponent object methods as appropriate.
Since (in your words) they have "unrelated class interfaces", you won't get any of the benefits of polymorphism.
It sounds like you are really inheriting from the Base class to implement the Mixin pattern.
Maybe composition is the better approach, where you include a copy of the Base class (which you will have to rename) in the VisualComponent or PhysicsComponent class.
However, based on the following question:
If I only have a reference or pointer
to Base what design options do I have
to expose the interface of
VisualComponent or PhysicsComponent?
Isn't the GameObject class (which you are instantiating in main()) already doing this for you?
Edit:
Okay, I think I understand better now that the question has been edited.
But I need some way to store all of
the Components dynamically in the
GameObject but still be able to use
their individual interfaces.
The only easy way I can see this working is by creating a virtual method in Base which is overridden in each derived class and implements class specific behaviour. GameObject could simply store a container of Base pointers and invoke the virtual method(s) which will be dispatched to the derived classes.
I would also recommend making Render(), Move() and any non-virtual methods private so that the GameObject class can only access the public (virtual) methods. The helps keep the public interface clean.
I'm not sure if this helps.
Edit 2:
After further discussion in the comments, it sounds like the factory pattern or the abstract factory pattern is what you need.

Visitor Pattern. If I understand what you are asking.
Though really need to know more context!

Take a look at boost.signals
You can define a signal for each message type and allow features to add slots (receivers) to it, this may be their member-functions of any name, or any other callable things of a proper signature.

Related

c++ what design will help avoid multiple inheritance when using listeners

I have larger project where many smaller classes listen to some data and in certain instances notify other classes. So i have classes like
class Calc {}
class Spotter {}
class Updater {}
....
and some other classes that listen to them
class Listener_1 {}
class Listener_2 {}
And the project ended up with many interfaces
class ICalcListener {
virtual void onCalcCall( ... ) {}
class ISpotterListener {
virtual void on SpotterCall( ... ) {}
....
And the listeners are not inheriting all the listeners and overwrite the callback where they need to react.
class Listener_1 : public ICalcListener, public ISpotterListener, ... {
virtual void onCalcCall( ... ) { doThis(); }
}
The design is functioning, but I am wondering if there is a better way to deal with this than Interfacing and inheriting myself to the maximum here. Mostly all I need is to register a callback.
EDIT:
I was poking round more and and it seems like the alternative to using interfaces is using ( I am using c11 )
1.) delegate
2.) std::function
3.) lambda function
If performance matters, but simplicity is also appreciated, what is the best way to go?
Multiple inheritance from several abstract classes with methods only is not that bad, and it works. I agree it produces a lot of "junky" code to support all the types of notifications you have.
Basically, having IXXXNotify abstract class for every event is more Java style.
I don't know exactly what your project is and how it does things, but you could try looking for these alternatives:
Stick to INotify abstract classes, but make it more generic, so they will have only one argument like Event which will carry on all required information including event type. This will reduce amount of interface classes but will introduce additional headache with switch statements on event types. This approach breaks "OOPness" of your code a bit.
Make a generic event/message bus, where again you'll have generic Event parameters and objects which interested in particular events can subscribe to them. Take a look at visitor or observer pattern and think of them in more generic way.
Use std::function as your "event handler". Drawback here is that you can only assign one handler to any given event. You can overcome this by adding a layer on top of std::function.
Take a look at existing libraries which already handle this, like Qt or boost.

Advice on a message handling system

I'm currently putting together a game engine as part of a university module and one part of it is a message handling system. I'm looking to improve on the lecturer's implementation, so any advice or criticism of my possible changes is most welcome.
Current Message structure
struct Message
{
Entity* entity;
std::string message;
void* data;
Message(Entity* entity, std::string message, void* data):
entity(entity), message(message), data(data) {}
};
The initial implementation only has messages being sent to Entities, but I plan on using an 'interface' to allow any component of the game engine to be able to receive messages.
class IMessageReceiver
{
public:
virtual void handleMessage(const Message& message) {}
};
struct Message
{
IMessageReceiver* receiver;
std::string message;
void* data;
};
//examples
class Entity : public IMessageReceiver { };
class Game : public IMessageReceiver { };
A problem I have with the current system is the void* for the data (I just don't like using void*). This is then cast to the type it needs to be inside the handleMessage function as I know what data it should be receiving (depending on the message string)- typically it has been either a 3D vector or an Entity up to this point, but if I have it sending messages to things other than Entities then this will likely change.
I wanted to change this to use a template instead; however, I'm not sure how I'd go about doing this.
template <typename T>
struct Message
{
IMessageReceiver* receiver;
std::string message;
T* data;
};
I'm somewhat familiar with templates, on a basic level, but I'm likely lacking some deeper knowledge of template trickery. I know I could pass it the type of the data when I create a new message.
//example
Entity* entity;
vec3 someVec;
Message<vec3> message(entity, "Fire", someVec);
MessageHandler::sendMessage(message);
But how would I then write up the handleMessage function declaration in IMessageReceiver, as different implementing classes will have different data in the messages sent to them?
virtual void handleMessage(const Message<?>& message) {}
I had the thought of making IMessageReceiver a template class as well, so when a class inherits from it they set the type of data the messages they receive will be.
template <typename T>
class IMessageReceiver
{
public:
virtual void handleMessage(const Message<T>& message) {}
};
class Entity : IMessageReceiver<vec3> {};
However, this means that a message receiver can only receive information of one type, but there could be an occasion where I might have to send data of different types to the same receiver- for example, a derived class of Entity usually receives a vec3 as the data part of the message but a new scenario requires it to receive another Entity.
Another issue with this I found is that only the abstract base class Entity inherits from IMessageReceiver (not every derived class of Entity and they receive different information of different types- or could), which would then mean making Entity a template class as well so this could be set by passing it on. But I would still have this inflexible system where something can only receive messages of one type of data.
Perhaps void* is the 'best' approach, and perhaps using an interface class is not. I don't know.
Please feel free to offer up any constructive criticism you can think of. I'm not asking someone to write it for me, I'm just looking for advice on a good way of implementing what I'm attempting to do. Basically, I want to be able to make any component of the engine be able to receive messages; the data that is sent in the message is not predefined; and preferably does not use void*.
Thank you for taking the time to read this. If you require any additional information please let me know.
Gavin
Virtual functions require the exact signature to be known at compile time, so you cannot use "template trickery" directly to achieve what you want.
Take a look at Boost.Any as a replacement for the void* Message::data. It still requires a cast of sorts to convert it to the correct type, but it is done in a type safe manner. Also, this way the message "owns" the data so you don't have to worry about lifetime issues.
Also, instead of using IMessageReceiver, consider std::function<void(const Message&)> instead. That way, you can pass the message to any object that has a void operator()(const Message&), and you don't have bother with the complexity of a hierarchy.
Both boost::any and std::function internally use a technique known as type erasure which takes the inheritance out of the interface and allows you to treat things as values, which tends to make the code simpler to reason about.
Your pattern suggests that the sender knows the receiver and will send the message directly to a single receiver, so you could have the sender simply call the receiver's method directly and that method could be overloaded with "message"-specific parameters (which also solves the problem of which object "owns" the dynamically allocated message data).
A common reason for making a messaging system rather than directly calling methods on the target is to reduce coupling between objects. The observer or publish/subscribe pattern reduces coupling by making the senders of messages (mostly) unaware of the receivers of the messages. In this case, you need a way to abstract message details, which seems to be what the question is about.
You could have a virtual base class for a message, and derive message-specific types from it. The handleMessage method could then take a pointer to the base class, and then use a dynamic_cast to downcast it to the concrete message type. This is slightly nicer than passing a void* and doing an arbitrary cast, as you'd at least get some run-time type checking.
Another option is to have multiple overloads in your IMessageReceiver interface (which all have no-op implementations) and to have message senders simply call the specific method directly. This gives you compile-time type checking, but requires a recompile whenever you invent a new "message" type. (I put message in quotation marks because, in this scheme, you no longer need message objects.)

Is it okay when a base class has only one derived class?

I am creating a password module using OOD and design patterns. The module will keep log of recordable events and read/write to a file. I created the interface in the base class and implementation in derived class. Now I am wondering if this is sort of bad smell if a base class has only one derived class. Is this kind of class hierarchy unnecessary? Now to eliminate the class hierarchy I can of course just do everything in one class and not derive at all, here is my code.
class CLogFile
{
public:
CLogFile(void);
virtual ~CLogFile(void);
virtual void Read(CString strLog) = 0;
virtual void Write(CString strNewMsg) = 0;
};
The derived class is:
class CLogFileImpl :
public CLogFile
{
public:
CLogFileImpl(CString strLogFileName, CString & strLog);
virtual ~CLogFileImpl(void);
virtual void Read(CString strLog);
virtual void Write(CString strNewMsg);
protected:
CString & m_strLog; // the log file data
CString m_strLogFileName; // file name
};
Now in the code
CLogFile * m_LogFile = new CLogFileImpl( m_strLogPath, m_strLog );
m_LogFile->Write("Log file created");
My question is that on one hand I am following OOD principal and creating interface first and implementation in a derived class. On the other hand is it an overkill and does it complicate things? My code is simple enough not to use any design patterns but it does get clues from it in terms of general data encapsulation through a derived class.
Ultimately is the above class hierarchy good or should it be done in one class instead?
No, in fact I believe your design is good. You may later need to add a mock or test implementation for your class and your design makes this easier.
The answer depends on how likely it is that you'll have more than one behavior for that interface.
Read and write operations for a file system might make perfect sense now. What if you decide to write to something remote, like a database? In that case, a new implementation still works perfectly without affecting clients.
I'd say this is a fine example of how to do an interface.
Shouldn't you make the destructor pure virtual? If I recall correctly, that's the recommended idiom for creating a C++ interface according to Scott Myers.
Yes, this is acceptable, even with only 1 implementation of your interface, but it may be slower at run time (slightly) than a single class. (virtual dispatch has roughly the cost of following 1-2 function pointers)
This can be used as a way of preventing dependencies on clients on the implementation details. As an example, clients of your interface do not need to be recompiled just because your implementation gets a new data field under your above pattern.
You can also look at the pImpl pattern, which is a way to hide implementation details without using inheritance.
Your model works well with the factory model where you work with a lot of shared-pointers and you call some factory method to "get you" a shared pointer to an abstract interface.
The downside of using pImpl is managing the pointer itself. With C++11 however the pImpl will work well with being movable so will be more workable. At present though, if you want to return an instance of your class from a "factory" function it has copy semantic issues with its internal pointer.
This leads to implementers either returning a shared pointer to the outer class, which is made non-copyable. That means you have a shared pointer to one class holding a pointer to an inner class so function calls go through that extra level of indirection and you get two "new"s per construction. If you have only a small number of these objects that isn't a major concern, but it can be a bit clumsy.
C++11 has the advantage of both having unique_ptr which supports forward declaration of its underlying and move semantics. Thus pImpl will become more feasible where you really do know you are going to have just one implementation.
Incidentally I would get rid of those CStrings and replace them with std::string, and not put C as a prefix to every class. I would also make the data members of the implementation private, not protected.
An alternative model you could have, as defined by Composition over Inheritance and Single Responsibility Principle, both referenced by Stephane Rolland, implemented the following model.
First, you need three different classes:
class CLog {
CLogReader* m_Reader;
CLogWriter* m_Writer;
public:
void Read(CString& strLog) {
m_Reader->Read(strLog);
}
void Write(const CString& strNewMsg) {
m_Writer->Write(strNewMsg);
}
void setReader(CLogReader* reader) {
m_Reader = reader;
}
void setWriter(CLogWriter* writer) {
m_Writer = writer;
}
};
CLogReader handles the Single Responsibility of reading logs:
class CLogReader {
public:
virtual void Read(CString& strLog) {
//read to the string.
}
};
CLogWriter handles the Single Responsibility of writing logs:
class CLogWriter {
public:
virtual void Write(const CString& strNewMsg) {
//Write the string;
}
};
Then, if you wanted your CLog to, say, write to a socket, you would derive CLogWriter:
class CLogSocketWriter : public CLogWriter {
public:
void Write(const CString& strNewMsg) {
//Write to socket?
}
};
And then set your CLog instance's Writer to an instance of CLogSocketWriter:
CLog* log = new CLog();
log->setWriter(new CLogSocketWriter());
log->Write("Write something to a socket");
Pros
The pros to this method are that you follow the Single Responsibility Principle in that every class has a single purpose. It gives you the ability to expand a single purpose without having to drag along code which you would not modify anyways. It also allows you to swap out components as you see fit, without having to create an entire new CLog class for that purpose. For instance, you could have a Writer that writes to a socket, but a reader that reads a local file. Etc.
Cons
Memory management becomes a huge concern here. You have to keep track of when to delete your pointers. In this case, you'd need to delete them on destruction of CLog, as well as when setting a different Writer or Reader. Doing this, if references are stored elsewhere, could lead to dangling pointers. This would be a great opportunity to learn about Strong and Weak references, which are reference counter containers, which automatically delete their pointer when all references to it are lost.
No. If there's no polymorphism in action there's no reason for inheritance and you should use the refactoring rule to put the two classes into one. "Prefer composition over inheritance".
Edit: as #crush commented, "prefer composition over inheritance" may not be the adequate quotation here. So let's say: if you think you need to use inheritance, think twice. And if ever you are really sure you need to use it, think about it once again.

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).

Which is better: Function overriding or passing a function pointer for event handling

So, I'm writing code for a class that will go into a library that will be used by others. This class will intercept and process incoming messages (details are not important but it's using the activemq-cpp library). The outline of this consumer class is
class MessageConsumer {
...
public:
void runConsumer();
virtual void onMessage(const Message* message);
}
where runConsumer() sets up the connection and starts listening and onMessage() is called when a message is received.
My questions is this: People who'll use this code will each have their own way of processing the different messages. How can I keep MessageConsumer generic but offer this flexibility, while keeping their code simple?
Two options:
Should they inherit a new class from MessageConsumer and write their own onMessage()?
Should they pass a pointer to a message handling function to MessageConsumer?
What do you think, which option is better and why?
Thanks!
In one approach, clients are allowed to register a callback and then the MessageConsumer invokes the registered callback. This is something like an observer/broadcast design pattern.
The second approach, where clients have to inherit and override MessageConsumer would be something like Strategy design pattern.
Basic design goals suggest to use the weakest relationship to promote loose coupling. Since inhertiance is a stronger relationship as compared to a simple association, everything else being the same Approach 1 is preferred.
From Herb's article
"Inheritance is often overused, even
by experienced developers. Always
minimize coupling: If a class
relationship can be expressed in more
than one way, use the weakest
relationship that's practical. Given
that inheritance is nearly the
strongest relationship you can express
in C++ (second only to friendship),
it's only really appropriate when
there is no equivalent weaker
alternative."
But as James points out, it is tough to comment unless the overall design constraints are known clearly.
Inheritance will make your library more OO-friendly and may improve readability. But really, the choices are about the same since the compiler will check that the user has supplied the function (assuming you declare a pure virtual handler in the base class), and the underlying mechanism will be accomplished via a pointer anyway (virtual table in the case of inheritance).
Pure virtual functions allow the compiler to check that the client code implements the handler. Virtual dispatch is active immediately after an object is constructed, and someone looking at the derived class can reason accurately about its handling. Data needed for the handling can be conveniently and clearly grouped into the derived class. Factories can still select a particular derived class to instantiate.
Function pointers are run-time state, so there's a little more care needed to initialise them in a timely fashion, for optional run-time checks on their being set and error handling, and to reason about which set is in effect during program execution. With that comes more freedom to vary them within the lifetime of the object.
A third alternative is a template policy class, or the Curiously Recurring Template Pattern, to lock in the behaviours at compile time. This potentially allows inlining of callbacks, dead-code elimination and other optimisations.
virtual function or tepmlated functor are the way to go. These approaches give greater flexibility ad looser coupling than function pointer one.
To illustrate that - function pointer approach can be wrapped with first two, but not vice-versa.
void cbFunction();
class Interface {
virtual void act() =0 ;
};
class CbFuctionWrapper:public Interface {
public:
virtual void act() {cbFunction()};
};
class AnotherImpl: public Interface {
Context _c; // You can't pass additional context with usual function without downcasting, but OO is all about that.
public:
virtual void act() {...}
}