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

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

Related

c++ templates, virtual funcs, empty base

Still getting the hang of c++ classes, and I'm wondering what is the most run-time-efficient way to accomplish this:
I have a derived class that I want to instantiate once (known at compile-time), but I want to typecast the pointer to a base class pointer and pass that around for the rest of my program to use. That way, if I have a future project where I want to change the instance from animal.dog to animal.cat, all other parts of my code will still be able to call the method animalPtr->eat(), but the actual behavior will be specific to dog or cat. I will only ever have 1 instance of animal.dog or animal.cat, and I will never have an instance of base-class animal.
Maybe doing exactly what I just described is exactly how I need to do it, but I read some online arguments about the pros and cons of having the base class "animal" use virtual functions versus having the base class be a template class (not exactly sure how to even make it into a template in this case....to me, templates classes looked like they were used for creating generic data types for the members, but that is not what I'm needing here).
Any help? Remember that speed-performance is the highest priority for me.
Using a virtual function is the object oriented way to solve this. With the usual implementation of virtual functions, it adds another pointer indirection and makes inlining impossible so if you really, really, really have performance issues and the function is small and called millions of times in a tight loop, then you might have a performance issue.
Use the virtual function approach to start with. If it is a problem (and you have measured that this is indeed the problem with a profiler), then you can look into changing things to a template based approach that might be more efficient.
to implement what you want w/o virtual functions can be done by templating the base class:
template<class Parent>
class BASE {
public:
BASE();
virtual ~BASE();
void func() {
reinterpret_cast<Parent*>(this)->func(); // call parent func
// or
(Parent*)(this)->func();
}
};
You can later typedef the BASE class to a normal class name:
typedef BASE<specific_Parent> myBASE;
It seems to me you are trying to decide between run-time and compile-time polymorphisms. If you do really need run-time polymorphism you have to use virtual functions. But if you don't really need run-time polymorphism, you can use CRTP to achieve the compile-time polymorphism.
This is a very primitive example illustrating the compile-time polymorphism (code on ideone.com):
#include <iostream>
namespace so {
template<typename _t_derived_>
class _animal_ {
private:
using _derived_ = _t_derived_;
public:
void eat() const {
static_cast<_derived_ const *>(this)->eat_impl();
}
};
class _dog_: public _animal_<_dog_> {
friend class _animal_<_dog_> ;
private:
using _base_ = _animal_<_dog_>;
protected:
void eat_impl() const {
std::cout << "dog's eating." << std::endl;
}
};
class _cat_: public _animal_<_cat_> {
friend class _animal_<_cat_> ;
private:
using _base_ = _animal_<_cat_>;
protected:
void eat_impl() const {
std::cout << "cat's eating." << std::endl;
}
};
template<typename _t_animal_>
void feed(_t_animal_ const & _animal) {
std::cout << "feeding an animal: ";
_animal.eat();
}
} // namespace so
int main() {
so::_dog_ dog_;
so::_cat_ cat_;
so::feed(dog_);
so::feed(cat_);
return (0);
}
Program output:
feeding an animal: dog's eating.
feeding an animal: cat's eating.

C++ Inheritance and Pthreads with Virtual Worker Functions

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.

Problems with C++ abstract class (I can do it in Java, but not in C++!)

First of all, I searched this problem and found a lot of similiar questions, but I couldn't find an answer that fixed my problem. I am very sorry if that is just me being dumb.
What I am trying to do is make the constructor of an abstract class call a function that is pure virtual. In Java, this works, because the subclass provides the implementation of the abstract method that is called. However, in C++, I get this linker error:
test.o:test.cpp:(.text$_ZN15MyAbstractClassC2Ev[MyAbstractClass::MyAbstractClass
()]+0x16): undefined reference to `MyAbstractClass::initialize()'
collect2: ld returned 1 exit status
Here is my code:
#include <iostream>
class MyAbstractClass {
protected:
virtual void initialize() = 0;
public:
MyAbstractClass() {
initialize();
}
};
class MyClass : public MyAbstractClass {
private:
void initialize() {
std::cout << "yey!" << std::endl;
}
};
int main() {
MyClass *my = new MyClass();
return 0;
}
As a further explanation of what I am trying to do, here is code in Java that achieves my goal:
public abstract class MyAbstractClass {
public MyAbstractClass() {
initialize();
}
protected abstract void initialize();
}
public class MyClass extends MyAbstractClass {
protected void initialize() {
System.out.println("Yey!");
}
public static void main(String[] args) {
MyClass myClass = new MyClass();
}
}
This code prints "Yey!". Any help much appreciated!
MyAbstractClass() {
initialize();
}
That will not perform a virtual dispatch to MyClass::initialize(), because at this stage of the object's construction its MyClass parts haven't been created yet. Thus you really are invoking MyAbstractClass::initialize() and, as such, it must be defined. (Yes, pure virtual member functions can be defined.)
Try to avoid invoking virtual member functions from constructors, because this sort of stuff will happen and catch you out. It rarely makes sense to do it.
Also, try to avoid initialize() functions; you already have constructors to play with.
Update
Actually, though you may take the above as read for any other virtual member function, invoking a pure virtual member function from the constructor yields Undefined Behaviour. So don't even try!
In C++, you can't call a pure virtual function from a constructor or destructor (even if it has a definition). If you call a non-pure one, then it will be dispatched as if the object's type were the class under construction, so you'll never be able to call a function defined in a derived class.
In this case, you don't need to; the derived class's constructor will be called after the base class's, so you get the desired result from:
#include <iostream>
class MyAbstractClass {
public:
MyAbstractClass() {
// don't do anything special to initialise the derived class
}
};
class MyClass : public MyAbstractClass {
public:
MyClass() {
std::cout << "yey!" << std::endl;
}
};
int main() {
MyClass my;
return 0;
}
Note that I also changed my to an automatic variable; you should get in the habit of using them whenever you don't need dynamic allocation, and learn how to use RAII to manage dynamic resources when you really do need them.
Let me quote Scott Meyers here (see Never Call Virtual Functions during Construction or Destruction):
Item 9: Never call virtual functions during construction or destruction.
I'll begin with the recap: you shouldn't call virtual functions during construction or destruction, because the calls won't do what you think, and if they did, you'd still be unhappy. If you're a recovering Java or C# programmer, pay close attention to this Item, because this is a place where those languages zig, while C++ zags.
The issue: during object construction the virtual function table might not yet be ready. Just imagine that your class is eg. fourth in line of inheritance. Constructors are called in inheritance order, so while calling this pure virtual (or even if it was non-pure) you would like the base class to call initialize for an object that is not yet complete!
The C++ side has been handled in other answers, but I want to add a remark on the Java side of it. Calling a virtual function from a constructor is a problem in all cases, not just in C++. Basically what the code is trying to do is execute a method on an object that has not yet been created and that is an error.
The two solutions implemented in the different languages differ in trying to make some sense of what your code is trying to do. In C++ the decision is that during construction of a base object, and until construction of the derived object starts, the actual type of the object is base, which means that there won't be dynamic dispatch. That is, the type of the object at any time is that of the constructor being executed[*]. While this is surprising to some (you among others), it provides a sensible solution to the problem.
[*] Conversely the destructor. The type also changes as the most derived constructors complete.
The alternative in Java is that the object is of the final type from the beginning, even before construction has completed. In Java, as you demonstrated, the call will be dispatched to the final overrider (I am using C++ slang here: to the last implementation of the virtual function in the execution chain), and that can cause unwanted behavior. Consider for example this implementation of initialize():
public class MyClass extends MyAbstractClass {
final int k1 = 1;
final int k2;
MyClass() {
k2 = 2;
}
void initialize() {
System.out.println( "Constant 1 is " + k1 + " and constant 2 is " + k2 );
}
}
What is the output of the previous program? (Answer at the bottom)
More than just a toy example, consider that MyClass provides some invariants that are set at construction time and hold for the whole lifetime of the object. Maybe it holds a reference to a logger on which data can be dumped. By looking at the class, you can see that the logger is set in the constructor and assume that it cannot be reset anywhere in the code:
public class MyClass extends MyAbstractClass {
Logger logger;
MyClass() {
logger = new Logger( System.out );
}
void initialize() {
logger.debug( "Starting initialization" );
}
}
You probably see now where this is going. By looking at the implementation of MyClass there does not seem to be anything wrong at all. logger is set in the constructor, so it can be used in all methods of the class. Now the problem is that if MyAbstractClass calls on a virtual function that gets dispatched then the application will crash with a NullPointerException.
By now I hope that you understand and value the C++ decision of not performing dynamic dispatch and thus avoid executing functions on objects that have not yet been fully initialized (or conversely have already been destroyed, if the virtual call is in the destructor).
(Answer: this might depend on the compiler/JVM, but when I tried this long long time ago, the line printed Constant 1 is 1 and constant 2 is 0. If you are happy with that, fine by me, but I found that to be surprising... The reason for the 1/0 in that compiler is that the process of initialization first sets the values that are in the variable definition, and then calls the constructors. This means that the first step of construction would set k1 before calling MyAbstractBase constructor, that would call initialize() before MyBase constructor has run and set the value of the second constant).
During construction and destruction, the virtual table is set up appropriately for the base subobject being constructed or destroyed. This is the theoretically correct thing to do, because the more-derived class is not alive (its lifetime either hasn't yet started or has already ended).
As already explained by #Seth, you cannot call virtual functions in a constructor. More specifically, the virtual dispatch mechanism is disabled during construction and destruction. Either make your initialize member function nonvirtual and implement it in the base class, or have the user call it explicitly.

Is it possible to have a base class method that calls the same (but overridden method) of all it's derived classes?

It's a bit hard to explain in words, so I'll give an example:
(The following code might have incorrect syntax but it suffices to give an idea)
class A
{
public:
static void Update(UINT someValue);
};
class B : public A
{
public:
static void Update(UINT someValue);
};
class C : public A
{
public:
static void Update(UINT someValue);
};
I know static members function do not override each other,
but let's suppose they do.
What I want to achieve, is when A::Update(someValue); is called,
It should implicitly call B::Update(someValue), and also C::Update(someValue), as well as call every static void Update(UINT someValue) method of other classes derived from A
Is this possible in one way or another?
And if it is, how would you do it?
I think you should be using composite pattern instead. You can read about it at http://en.wikipedia.org/wiki/Composite_pattern and http://www.javacamp.org/designPattern/composite.html
That info below my comment is not enough to have a clear idea about your code but I was thinking if it is possible to do something similar to what C# does with events, where you can register events and the class that triggers then (your base class in that case) can implement a list of function pointers (pointing to the derived methods, which in that case you have to have instances of the derived classes) and call all of then iterating this list. Just an idea, don't know if this is what you need.
There's no way to do it automatically. A simple way to get the effect is for each derived class to call the function of its base class:
class A
{
public:
static void Update(UINT someValue) {
std::cout << "A\n";
}
};
class B : public A
{
public:
static void Update(UINT someValue) {
A::Update(someValue);
std::cout << "B\n";
}
};
If you prefer to work from bottom to top, you could have each class do its work before calling the derived class. Of course there's nothing to stop a derived class from implementing Update and not calling its base class. It is however fine for a class to not implement Update at all -- it doesn't care about updates, but its base class's function can still be called. So it's not a huge burden on implementers, they just have to follow the rule that if they implement the function, they have to call the base.
Another way might be for the base class to keep a list of "listeners" who are interested in updates, and to call them in turn whenever an update occurs. Each derived class can then register a suitable listener.
It might be difficult to make code like this exception-safe, though, if each level makes changes but one or more levels may throw.

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;
};