Search code examples
c++derived-classbase-class

Which derived class object called the non-virtual function in the base class


Background:

I have a base class, Base, which has mostly 'pure' virtual functions and some non-virtual functions (plus a couple of virtual functions).

Basically, the common functionality in all the derived classes Derived, Derived2, etc, is present in the base class as non-virtual functions.

Question: If one of the objects from any of the derived classes, calls any of the non-virtual functions from the Base class, how (if at all) could it be possible to know which derived-class-object has called this non-virtual base-class function.

Actually, I wanted to debug one call and stumbled upon the fact that, neither with the debugger nor with any tracelines, can I ascertain from which derived-class-object did I stumble into this non-virtual base-class-function.

Come to think of it, as I was writing this question, one way, I can think is, I could have a static member string variable in each derived class and pass that as an argument to the non-virtual base class functions. But, is that the only way?

Minimum Working Example: Here is the minimum working example. I stripped it down as far as possible.

#include <iostream>


#include <pthread.h>
#include <string>
#include <errno.h>
#include <cstring>

class Base {
public:
    Base() {}
    virtual ~Base() {}
    int waitForThreadToExit() {
        int error = pthread_join(m_Thread, NULL);
        if (0 != error) {
            std::cerr << "Error from pthread_join(). errorCode:" << strerror(errno) << std::endl;
        }
        return error;
    }

    int start() {
        if ((startThread()) != 0) {
             std::cerr << "error returned from the start() function." << std::endl;
         }
    }

protected:
    virtual int runThread(void) {
      std::cout << "Reimplement" << std::endl;;
      return -1;
    }
    int startThread() {
        int error = pthread_create(&m_Thread, NULL, internalThreadEntryFunc, this);
        return error;
    }

private:
    static void* internalThreadEntryFunc(void* This) {
        ((Base *) This)->runThread();
        return NULL;
    }
    pthread_t m_Thread;
};


class Derived: public Base {
public:
    Derived() {}
    virtual ~Derived() {}

private:
    virtual int runThread(void) {
        while(1) {
             std::cout << "Sehr gut!" << std::endl;;
             return 0;
        }
    }

};

class Derived2: public Base {
public:
    Derived2() {}
    virtual ~Derived2() {}

private:
    virtual int runThread(void) {
        while (1)
        {
            std::cout << "Sehr sehr gut!" << std::endl;;
            return 0;
        }
    }

};


int main()
{
    std::cout << "Hello World!" << std::endl;
    Derived d;
    Derived2 d2;
    d.start();
    d2.start();
    d.waitForThreadToExit();
    d2.waitForThreadToExit();
    return 0;
}

Solution

  • So just to be complete, in case someone else (quite possibly me myself in a few months time) stumbles upon this question again, here is the general idea that I implemented for this problem.

    #include <iostream>
    #include <typeinfo>
    
    class base {
    public:
        virtual const char* name() {
            return typeid(*this).name();
        }
        virtual ~base(){}
    };
    
    class derived : public base {};
    class otherDerived : public base {};
    
    int main () {
        base b;
        derived d;
        otherDerived d2;
    
        std::cout << "base says:" << b.name() << std::endl;
        std::cout << "derived says:" << d.name() << std::endl;
        std::cout << "other derived says:" << d2.name() << std::endl;
    }
    

    which gives the output when run in my QtCreator:

    base says:4base
    derived says:7dervied
    other derived says:12otherDerived

    Note: Best to make a virtual function name() or className() and call that functio n everywhere, instead of sprinkling typeid(*this).name() everywhere in the code.