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.
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().
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().
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();
}
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;
}
}
};
Related
For example, say I have a basic data object class as below.
class DataObject {
protected:
bool data_changed;
virtual void save() {}
virtual void load() {}
public:
virtual void idle() {
if (data_changed) {
save();
data_changed = false;
}
}
};
The idea is that "idle" is called periodically from some main looping thread and performs non-critical updates.
Now I want derived classes to be able to have their own idle functions. But I don't want to lose the default behavior.
One solution is to say "remember to call DataObject::idle() from overridden idle() functions".
Like this:
class ChildData : public DataObject {
public:
virtual void idle() override {
//do something
DataObject::idle(); //remember to call parent idle!
}
};
But this is very dangerous as people can just forget.
Is there a way to enforce this somehow? Or make it automatic, like a virtual destructor?
(My current "workaround" is to have 2 functions, one the parent_idle that does the important stuff, and then one overridable child_idle that derived functions can override. But this is a bit messy, and also you have to make a whole new set of functions again if you want some child function to enforce its own default...)
Maybe you could write it:
...
void idle_start() { // not virtual, main looping thread calls this
idle();
if (data_changed) {
save();
data_changed = false;
}
}
virtual void idle() { } // virtual, noop by default
...
That depends if you want to have your derived behavior before the mandatory base behavior.
I am trying to use a method from a child that class that inherits from a interface. The call to that method done from a client class (main method).
//interface method
class InterfaceMethod{
virtual void method(void) = 0;
}
This is the class that is inheritance the interface:
class ChildClass: public InterfaceMethod
{
public:
ChildClass(){}
~ ChildClass(){}
//virtual method implementation
void method(void)
{
//do stuff
}
//and this is the method that i want to use!
//a method declared in the child class
void anotherMethod()
{
//Do another stuff
}
private:
}
This is the client:
int main()
{
InterfaceMethod * aClient= new ChildClass;
//tryng to access the child method
(ChildClass)(*aClient).anotherMethod();//This is nor allowed by the compiler!!!
}
You want dynamic cast.
ChildClass * child = dynamic_cast<ChildClass*>(aClient);
if(child){ //cast sucess
child->anotherMethod();
}else{
//cast failed, wrong type
}
Try it like this:
static_cast<ChildClass*>(aClient)->anotherMethod();
You shouldn't do this unless you can be sure that you have an instance of the derived class.
Hi I have the following C++ code,
I have MyThread class in the thread.h file
class MyThread
{
public:
void start();
virtual void* task() = 0;
};
I have worker class in the worker.h file
class Worker : public MyThread
{
virtual ~Worker();
virtual void* task(); // I have implementation in worker.cpp
};
Have used pthread_create() in the start() in thread.cpp file for creating a thread and I want to make the task() routine defined in the worker.cpp as the start routine . So how can I do that ? What should I pass as the parameter to the start routine in pthread_create ?
I have tried this but it gives an error:
pthread_create(&(this->threadId),&(this->attr),(void *)task,NULL);
You can't use member function as a thread function. You can only use free functions or static member functions, but you can pass arbitrary void* argument to that function and you can pass pointer to this as that argument, that allows you to call member function inside that function:
class MyThread
{
public:
void start();
virtual void* task() = 0;
static void * thread_routine(void* pthis)
{
MyThread* t = static_cast<MyThread*>(pthis);
t->task();
return 0;
}
};
Then you launch your thread like this
void MyThread::start()
{
pthread_create(&(this->threadId),&(this->attr),thread_routine, this);
}
You can't use task() as start routine for the thread because it is a member function instead of a free function, like the expected signature void *(*start_routine)(void*). (also, it doesn't have the pointer to void parameter)
I would just create a wrapper and have it as the start routine, something like this:
void *wrapper(void *data)
{
Worker worker;
worker.task();
}
I have a base class MyScreen & I would like to always call the function initComponents() inside its constructor, even for sub classes of this class. But if the sub-class has overridden the initComponents() function, then I want MyClass to call the Sub-classes version of initComponents() not the super classes(MyScreen) version of initComponents().
Is it possible to do this from within MyClasses constructor?
class MyScreen
{
public:
MyScreen()
{
// a child of this class (& any instance of this class) should always call the initComponents() from this constructor
initComponents();
}
void initComponents()
{
// initialise mainLayout, etc, usually this function wont be overridden, sometimes it will be
}
protected:
Layout *mainLayout;
};
class MenuScreen : public MyScreen
{
public:
MenuScreen : public MyScreen()
{
// I know I could just call initComponents from here, but this is just an example, somethings must be called from the base class
}
void initComponents()
{
// create layout, set main layout etc.
mainLayout = new MenuLayout(...);
}
};
You shouldn't (or maybe even cannot) do that. The problem is that when constructing an object of your derived class, the base-class constructor is always called before the derived class's. This means that the derived object is not yet created, so its members will not be initialized (this will probabely also be valid for the v-table, so virtual function calls won't work). check this article
Instead you should call the initComponents by the user of your class explicitly and mark it virtual
No, you can't do this. The dynamic type of the object is always MyScreen inside MyScreen's constructor. You cannot call a MenuScreen function from inside it.
Populating a resource by calling a virtual function is possible by using inner classes. Here is an example
#ifndef CLAZYSTATICRESOURCINITIALIZATIONASPECT_H
#define CLAZYSTATICRESOURCINITIALIZATIONASPECT_H
#include <boost/thread/mutex.hpp>
template <typename R>
class CLazyStaticResourceInitialization
{
public:
/**
* Destructor
*/
virtual ~CLazyStaticResourceInitialization()
{
}
protected:
/**
* Internal class used for calling virtual function from constructor
*/
struct parent_virtual
{
/**
* Virtual destructor
*/
virtual ~parent_virtual ()
{
}
/**
* Virtual method implemented by parent class is necessary
*/
virtual void initializeOnce () const
{
}
};
/**
* Constructor that can call a virtual function of the parent
* #param obj specifies the virtual function
*/
CLazyStaticResourceInitialization(const parent_virtual& obj )
{
boost::mutex::scoped_lock scoped_lock(m_Mutex);
//Initialize the resource only once
if (isInitialized () == false)
{
obj.initializeOnce ();
setInitialized ();
}
}
/**
* Returns if any instance of this class has been initialized or not
* #return true if initialized, false otherwise
*/
bool isInitialized () const
{
return m_bInitialized;;
}
/**
* Returns if any instance of this class has been initialized or not
*/
void setInitialized ()
{
m_bInitialized = true;
}
protected:
/**
* The flag that indicates whether this class is initialized or not
*/
static volatile bool m_bInitialized;
/**
* The resource instance
*/
static R m_Resource;
/**
* The mutex to protect initialized flag
*/
static boost::mutex m_Mutex;
};
//Assume that this class is not initialized in the beginning
template <typename R> volatile bool CLazyStaticResourceInitialization<R>::m_bInitialized = false;
//Create a static instance of resource
template <typename R> R CLazyStaticResourceInitialization<R>::m_Resource;
//Create a static instance of mutex
template <typename R> boost::mutex CLazyStaticResourceInitialization<R>::m_Mutex;
#endif
And here is how you can use it
class CTestLazyInitialized : public CLazyStaticResourceInitialization <std::vector<int> >
{
public:
CTestLazyInitialized():
CLazyStaticResourceInitialization<std::vector<int> >(lazyderived_virtual())
{
}
unsigned int size ()
{
return this->m_Resource.size ();
}
protected:
struct lazyderived_virtual : public CLazyStaticResourceInitialization <std::vector<int> >::parent_virtual
{
lazyderived_virtual ()
{
}
void initializeOnce () const
{
m_Resource.push_back (1);
}
};
};
Just pay attention to inner classes used in both base and derived classes. The mutex locking and template stuff can be ignored for your case.
Class Test{
int value;
static void* thread_func(void* args){
value++;
}
void newthread(){
pthread_create(&thread_func,...);
}
}
I'm trying to create a thread in Class Test. Therefore compiler forces me to make thread_func static. However I cannot access the non-static member "value" anymore. It says:
invalid use of member 'Class::value' in static member function
Is there a way around it?
However I cannot access the non-static
member "value" anymore.
That is because static function in your class doesn't have (and cannot have ) this pointer. All you need to pass the pointer to your Test object to pthread_create() function as fourth argument, and then do this:
static void* thread_func(void* args)
{
Test *test = static_cast<Test*>(args);
test->value++;
//write return statement properly
}
However, if you're doing too many things in thread_func() that require access to Test class members at many places, then I would suggest this design:
//this design simplifies the syntax to access the class members!
class Test
{
//code omitted for brevity
static void* thread_func(void* args)
{
Test *test = static_cast<Test*>(args);
test->run(); //call the member function!
//write return statement properly
}
void run() //define a member function to run the thread!
{
value++;//now you can do this, because it is same as 'this->value++;
//you do have 'this' pointer here, as usual;
//so access other members like 'value++'.
}
//code omitted for brevity
}
Better design : define a reusable class!
Even better would be to define a reusable class with pure virtual function run() to be implemented by the derived classes. Here is how it should be designed:
//runnable is reusable class. All thread classes must derive from it!
class runnable
{
public:
virtual ~runnable() {}
static void run_thread(void *args)
{
runnable *prunnable = static_cast<runnable*>(args);
prunnable->run();
}
protected:
virtual void run() = 0; //derived class must implement this!
};
class Test : public runnable //derived from runnable!
{
public:
void newthread()
{
//note &runnable::run_thread
pthread_create(&runnable::run_thread,..., this);
}
protected:
void run() //implementing the virtual function!
{
value++; // your thread function!
}
}
Looks better?
Let thread_func take a pointer to an object of the class as argument.
static void* thread_func(void* pThis)
{
static_cast<Test*>(pThis)->value++;
}
In case, this method wants to take some other information as well, put both in another struct/class and pass that in.