tags:

views:

353

answers:

4

Hello,

I'm very new to c++, but I think I understand what is going on. The parent class is trying to call the pure virtual member function in the parent class. I thought that by overriding the virtual function in the child class, it would be called instead.

What am I doing wrong?

Provided for me in parent.h

class Parent
{
public:
virtual void run() = 0;
protected:
/** The function to starter routine and it will call run() defined by the
 * appropriate child class.
 * @param arg Arguments for the starter function
 */
static void * init (void * arg);
};

I'm trying to do this in parent.cpp

void * Parent::init(void * arg)
{
  run();
}

In my child.h I have this:

class Child : public Parent
{public:
//...
virtual void run();
//...
};

And in child.cpp I have:

void Child::run()
{
   sleep(10);
}

The function init in parent.cpp is where this fails to compile. How do I call a derived function from the parent class? All my googleing has only turned up notes about not calling virtual functions in the child's constructor.

Any help at all would be appreciated.

+9  A: 

run() is an instance member. Parent::init is a static (class-level) member. So in your init() implementation, there is no instance (of Parent or Child) available on which to call run().

itowlson
+5  A: 

You're trying to call an instance method from a static method. You'll need to change init() to be an instance method (by removing the static keyword) or else you'll need to call the run() method using an object, e.g. obj->run() or obj.run().

Justin Grant
+2  A: 

Do you know the actual type of arg: is it in fact a Parent instance? If so, then ...

void Parent::init(void* arg)
{
  Parent* self = static_cast<Parent*>(arg);
  self->run();
}
ChrisW
I think this solved it for me. I was calling init from a pthread_create, and had control of what got passed as the argument to the function, but had no idea at all what to pass in. Thanks!! I never would have figured this out on my own.
Derek Jurykovsky
Yes it's a typical implementation of C++ `Thread` class.
ChrisW
A: 

Look at this example that I recently provided here:

/** calls thread_func in a new thread passing it user_data as argument */
thrd_hdl c_api_thread_start(void (*thread_func)(void*), void* user_data);

/** abstract thread base class
* override my_thread::run to do work in another thread
*/
class my_thread {
  public:
    my_thread() hdl_(c_api_thread_start(my_thread::thread_runner,this)) {}
    // ...

  private:
    virtual int run() = 0; // we don't want this to be called from others

    thrd_hdl_t hdl_; // whatever the C threading API uses as a thread handle

    static int thread_runner(void* user_data)
    {
      my_thread* that = reinterpret_cast<my_thread*>(user_data);
      try {
        return that->run();
      } catch(...) {
        return oh_my_an_unknown_error;
      }
    }
};
sbi