C++ Inheritance and Pthreads with Virtual Worker Functions - c++

I have a class that I'm trying to implement as an abstract class to maximize code reuse. However, a major part of the commonality between the two derived classes lies in the fact that each has a consumer and producer thread. I'm wondering if I can have each static member function call a virtual member function that does all of the underlying work.
Basically, is the following code allowed or am I doing something super hacky, or will the compiler yell/scream at me?
// in AbstractClass.h
class AbstractClass {
// some code here including constructors/destructors
protected:
virtual int Worker() = 0; // derived class provides implementation
private:
static void* Thread(void* args);
};
// in AbstractClass.cpp
static void* AbstractClass::Thread(void* args) {
AbstractClass myobject = static_cast<AbstractClass*>(args);
myobject->Worker();
}
Basically I'm wondering if the derived class "worker" will ever be called this way? Note that p_thread_create() is called with passing in the Thread() function.
Thanks for the help as I try to improve my understanding of inheritance and virtual functions and how I can use it to maximize code reuse.

Yes the code looks fine and your assumptions are correct. The purpose of virtual functions is that the most derived version of a function will be called no matter which superclass signature the method is called on.
Using pthreads and C++, the approach you are using is perfectly reasonable and not hackey. However, I would create the threads in a separate class which would contain the static class method. This would stop the threads from being mixed up in your derived classes.
struct ThreadManager
{
ThreadManager(AbstractWorker* worker)
{
mWorker = worker;
mThread = ThreadStart(threadFunc, this); /* made up thread code :) */
}
~ThreadManager()
{
ThreadStop(mThread);
}
static void* threadFunc(void* args)
{
ThreadManager* manager = static_cast<ThreadManager*>(args);
manager->mWorker->Work();
}
AbstractWorker* mWorker;
Thread mThread;
}
Note that when using pthreads a static function is actually required.

Related

C++ is there a way to force invocation of base class method from overriding method?

I was wondering if, in modern C++, there is a way to force invocation of base class method from the method that is currently overriding it.
Let's look at an example scenario like the following:
class Base
{
public:
virtual void initialize()
{
... initialization stuff common to all subclasses ...
}
};
class Derived
{
public:
virtual void initialize() override
{
Base::initialize(); // !! I can forget to do this!
... initialization stuff specific to Derived class ...
}
};
I wonder if there is a way to force (at compile time) the invocation of base method from derived method, in order to avoid to forget some important initialization stuff provided by base class.
A possible ugly solution, that I adopt now, is the following (a sort of basic usage of the template method design pattern):
class Base
{
public:
void initialize() // note: this is not virtual
{
... initialization stuff common to all subclasses ...
this->_innerInitialize();
}
protected:
virtual void _innerInitialize() // actual virtual method to be overridden by subclasses
{
}
};
class Derived
{
virtual void _innerInitialize() override
{
... initialization stuff specific to Derived class ...
}
};
Does modern C++ offers a more elegant way to enforce this mechanism? Thank you all in advance.
Edit: since a lot of people are focusing about the initialize() method, the question was more general, not just for initialization methods, although the separation of construction and initialization is sometimes useful (for example for wrapper objects that encapsulate OpenGL entities, where sometimes you have to delay the initialization to a moment where a valid OpenGL context is available).

C++ Inheritance and Pointer-To-Member-Functions in combination with threads

currently I'm working on an implementation of a simple HTTP-Webserver (for practise purpose). My class WebServer needs to have a thread to listen for new connections and different threads for reponse handling. I'm not a fan of the way threads are used in C++ so I want to create some abstraction. Therefor I coded the following for easier object-orientated handling with threads (still work in progress)
#include<thread>
#include<chrono>
#include<iostream>
#include "ConnectionListener.h"
class Base {
public:
void start() {
thread = std::thread(&Base::run, this);
}
protected:
virtual void run() = 0;
private:
std::thread thread;
};
class Derived : public Base {
private:
void run() {
while (true) {
std::cout << "Running" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
};
int main() {
Derived d;
d.start();
std::this_thread::sleep_for(std::chrono::seconds(10));
}
This base class should be some sort of interface. The target is, that one can use the start member function of the derived class and have the run member function of the derived class executed in a new thread.
Now my problem / question:
I've learned that one can pass member functions to the thread constructor using pointer-to-member-functions. This is the reason I used &Base::run. But now I'm unsure if the run method of the base class will be executed or the run method of the derived class. My assumption: Due to the fact that we have a pure virtual run function in the base class, the member function of the derived class is used. But: What if the run member function in the base class isn't pure virtual but virtual? Does the execution then depend on the passed object reference (this)?
Hope you can understand what I mean. I'm a bit confused by the concept of pointer-to-member-function in combination with threads and inheritance. The concepts of polymorphism are clear to me. Hope you can help me out.
Greeting,
Tmirror

Forbid code to compile if some function is not called

Is there a way in C++ to forbid code to compile if the specific function was not called.
Imagine I have some class:
class CExample
{
public:
void Init();
void DoWork();
};
Is there a way to forbid calling DoWork() if the Init() function was not called for class object?
I want to forbid writing such a code:
CExample e;
e.DoWork();
and permit this version:
CExample e;
e.Init();
e.DoWork();
Can I reach this behaviour somehow with metaprogramming?
You can just use a constructor instead of Init.
In his notes about exception safety in the standard library, as appendix to the 3rd edition of The C++ Programming Language, Bjarne Stroustrup discussed how using init functions is at odds with the notion of class invariant. It's generally Bad Practiceâ„¢, mainly for that reason.
Some old GUI frameworks like Microsoft's MFC used init functions in order to do derived class specific initialization. There are other techniques to do that, including just passing the required information up the construction chain via arguments.
No, that would be bad design. If it must be called for the object to be usable, it should be called in the constructor. After an object is constructed, all public methods should be callable-- the object should be fully constructed and ready for use.
At compile time it is not known if Init() has been called before DoWork(). This can only be decided at runtime. Therefore metaprogramming will not be useful here.
You should put your init code into the constructor to enforce that the class is properly constructed. However if you really insist, and your init function really isn't polymorphic you can use CRTP with a protected constructor:
template <typename What>
class InitMe : public What
{
public:
InitMe() : What() { this->Init(); }
};
class CExample
{
public:
void Init() {}
void DoWork() {}
protected:
CExample() {}
};
int main()
{
//CExample e; // Error: protected constructor.
InitMe<CExample> e;
e.DoWork();
}
As Cheers and hth. -Alf and Rob K have both touched on, you most definitely want to have your init work performed in your class constructor. Having to call a separate function to ensure your class is properly ready is poor design.
However, that being said, you can detect if it's been called and act accordingly anyway:
void CExample::Init()
{
// things
...
init = true;
}
void CExample::DoWork()
{
if (!init)
{
Init();
}
}

Getting OOP right

Ok, this is my problem. I have the following classes:
class Job {
bool isComplete() {}
void setComplete() {}
//other functions
};
class SongJob: public Job {
vector<Job> v;
string getArtist() {}
void setArtist() {}
void addTrack() {}
string getTrack() {}
// other functions
};
// This were already implemeted
Now I want to implement a VideoJob and derived it from Job. But here is my problem. I also have the following function witch it was set to work only with SongJob:
void process(SongJob s)
{
// not the real functions
s.setArtist();
..............
s.getArtist();
.............
s.getArtist();
...............
s.setArtist()
}
Here I just want it to show that the function uses only derived object methods. So if I have another object derived from Job, I will need to change the parameter to Job, but then the compiler would not know about thoose functions and I dont what to test for everyone what kind of object it is and then cast it so I can call the correct function.
So it is okay to put all the functions in the base class, because then I will have no problem, but I don't know if this is correct OOP, if one class deals with Songs and the other with videos, I thing good oop means to have 2 clases.
If I didn't make myself clear, please say so and I will try explaining better.
And in short words, I want to use polymorfism.
It is totally fine to put all the things that the classes SongJob and VideoJob have in common into a common base-class. However, this will cause problems once you want to add a subclass of Job that has nothing to do with artists.
There are some things to note about the code you have posted. First, your class Job is apparently not an abstract base class. This means that you can have jobs that are just jobs. Not SongJob and not VideoJob. If you want to make it clear that there can not be a simple Job, make the base-class abstract:
class Job {
virtual bool isComplete() = 0;
virtual void setComplete() = 0;
//other functions
};
Now, you cannot create instances of Job:
Job job; // compiler-error
std::vector<Job> jobs; // compiler-error
Note that the functions are now virtual, which means that subclasses can override them. The = 0 and the end means that subclasses have to provide an implementation of these functions (they are pure virtual member functions).
Secondly, your class SongJob has a member std::vector<Job>. This is almost certainly not what you want. If you add a SongJob to this vector, it will become a normal Job. This effect is called slicing. To prevent it, you'd have to make it a std::vector<Job*>.
There is much more to say here, but that would go to far. I suggest you get a good book.
In your Base class Job you could add those methods as virtual methods so that a class deriving from Job may or may not override these specific methods.
In your SongJob class you override the methods and dont override them in VideoJob
In, void process() pass a pointer to Base class Job
void process(Job *s)
It will then call the appropriate methods depending on the adress of the objec s is pointing to which will be a SongJob object.
In C++, you have to do two things to get polymorphism to work:
Access polymorphic functions by a reference (&) or pointer (*) to a base type
Define the polymorphic functions as virtual in the base type
So, change these from:
class Job {
bool isComplete() {}
void setComplete() {}
};
void process(SongJob s)
{
// ...
}
To:
class Job {
public: // You forgot this...
virtual bool isComplete() { }
virtual void setComplete() { }
};
void process(Job& s)
{
// ...
}
If you can't define all the functionality you need inside process on your base class (if all the member functions you'd want don't apply to all the derived types), then you need to turn process into a member function on Job, and make it virtual:
class Job {
public:
virtual bool isComplete() { }
virtual void setComplete() { }
virtual void process() = 0;
};
// ...
int main(int argc, char* argv[])
{
SongJob sj;
Job& jobByRef = sj;
Job* jobByPointer = new SongJob();
// These call the derived implementation of process, on SongJob
jobByRef.process();
jobByPointer->process();
delete jobByPointer;
jobByPointer = new VideoJob();
// This calls the derived implementation of process, on VideoJob
jobByPointer->process();
return 0;
}
And of course, you'll have two different implementations of process. One for each class type.
People will tell you all sorts of "is-a" vs "has-a" stuff, and all sorts of complicated things about this silly "polymorphism" thing; and they're correct.
But this is basically the point of polymorphism, in a utilitarian sense: It is so you don't have to go around checking what type each class it before calling functions on it. You can just call functions on a base type, and the right derived implementation will get called in the end.
BTW, in C++, virtual ... someFunc(...) = 0; means that the type that function is defined in cannot be instantiated, and must be implemented in a derived class. It is called a "pure virtual" function, and the class it is defined on becomes "abstract".
Your problem comes from the fact you're calling a process method on an object. You should have a method Process on the Job class and override this method in your derived classes.
use pure virtual functions:
class Job
{
virtual string getArtist() =0;
};

C++ Inheritance Question edit: more troubles

I have a base class MessageHandler and 2 derived classes, MessageHandler_CB and MessageHandler_DQ.
The derived classes redefine the handleMessage(...) method. MH_DQ processes a message and puts the result in a deque while MH_CB processes the message and then executes a callback function.
The base class has a static callback function that I pass along with a this pointer to a library which calls the static callback when a new message is available for processing.
My problem comes when I am in the static callback with a void * pointing to either a MH_DQ or a MH_CB. If I cast it to the base class the empty MessageHandler::handleMessage(...) method is called, rather than the version in the appropriate derived class.
What is the best way to address this situation from a design perspective and/or what language features might help me to implement a solution to my problem?
Thanks in advance!
Okay, the virtual method did not work like magic. There is a twist to the story. I have a static method in the base class and a pure virtual member function to handle the message processing, but I want to first call a member function in the pure virtual base class to preprocess the message before I route it to the derived class.
So I have :
class MH {
...
static int CallBackFunction(MessageData *md, void *this_ptr) {
((MH *)this_ptr)->preprocess(md);
return 1;
}
virtual int preprocess(MessageData *md) {
// do some stuff
. . .
handleMessage(md);
return 1;
}
virtual void handleMessage(MessageData *) = 0;
};
class MH_CB : public MH {
...
void handleMessage(MessageData *md) {
// do something
...
}
};
class MH_DQ : public MH {
...
void handleMessage(MessageData *md) {
// do something different
...
}
};
Unfortunately, this code produces a run-time error that a pure virtual function is being called. Any thoughts?
TIA
Make the original method call virtual.
Don't pass a void* in the callback - pass a pointer to the base class, and declare handleMessage to be virtual.
Add the virtual keyword to the declaration/definition of the method in the base class.
In fact if the method in the base class is never supposed to run then you can specify that it's pure virtual to declare it with no body at all, instead of defining an empty body:
class MessageHandler
{
public:
virtual void handleMessage(...) = 0;
};
Mark the handleMessage() as virtual by prefixing void handleMessage() or whatever declaration in the base class with the word virtual. Then, make sure that the derived classes implement the exact same message signature (i.e. same return type and parameter types).
Also- instead of a void* use a MessageHandlerBase* (or whatever is appropriate). Then you don't need to cast. Casting is often the sign of a logic error on the part of the programmer.