pointer to function, class as parameter

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
kmindi
Earned a small fee
Earned a small fee
Posts: 21
Joined: Sun Jan 07, 2007 7:40 pm

pointer to function, class as parameter

Post by kmindi »

Hello.

I have a class called Thread derived from wxThread.
Every derived class from wxThread needs a Entry() function where the execution of this thread starts.

I did not want to make several classes that differ only in the entry()-function (which all called different memberfunctions of my "main"class.).

Thats why i put a function pointer as parameter in the constructor of the Thread-class.

here is the code i am going to talk about:

Code: Select all

//thread.h
#include <wx/thread.h>

class Thread : public wxThread 
{
    private:
        void (Zentrale::*adress)(); // pointer to be accessed by Entry
    
    public:
        Thread(void (Zentrale::*functiontocall)());
        ~Thread();
        virtual void* Entry();
};

Code: Select all

//thread.cpp
#include <zentrale.h> //definnition of the class Zentrale
#include <thread.h>
DECLARE_APP(Zentrale) //needed for wxGetApp()

//this class is a friend of the Zentrale-class
Thread::Thread(void (Zentrale::*functiontocall)()) 
{
   
   adress = functiontocall; //copy adress of passed function to temporary pointer
}
Thread::~Thread() { }

void *Thread::Entry() 
{
    (wxGetApp().*adress)();
}

Code: Select all

//...
//in a memberfunction of Zentrale
    Thread *thread = new Thread(&Zentrale::recv_thread); 
    Thread *thread2 = new Thread(&Zentrale::call_thread); 
    if (thread->Create() == wxTHREAD_NO_ERROR) { thread->Run(); }
    if (thread2->Create() == wxTHREAD_NO_ERROR) { thread2->Run(); }
//...
now there are two things i want to get rid off:
the first thing is, i pass the adress of the function in Zentrale to the constructor and there this adress has to be copied in a temporary pointer (of course of the same type) that the adress can be used in Entry to access the function.
how can i avoid this second pointer?



the second thing is:
how can i make this Thread class to not say by default that the passed pointer is a pointer to a memberfunction of the Zentrale class, but a pointer to a user-defined class.
The Thread class should accept any class, how can i make that? if you know what i mean ;)
20000 kbit/s | 1176 kbit/s | 10ms
NB: M-C2D P9500 | 9800M GTS | 2048 MiB DDR3 | 160 GB | Windows XP SP3
SERVER: XP 2800+ | 1024 MiB DDR-400 | 2*500 GB SATA | Debian 5.0
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

About #2 : templates :)

Code: Select all

template<typename T>
class Thread : public wxThread
{
    private:
        void (T::*adress)(); // pointer to be accessed by Entry
   
    public:
        Thread(void (T::*functiontocall)());
        ~Thread();
        virtual void* Entry();
};
// ...
Thread<Zentrale> *thread;
etc.

I'm not sure I understand #1. In any case, I don't see any way to remove pointers.
kmindi
Earned a small fee
Earned a small fee
Posts: 21
Joined: Sun Jan 07, 2007 7:40 pm

Post by kmindi »

Auria wrote:About #2 : templates :)

Code: Select all

template<typename T>
class Thread : public wxThread
{
    private:
        void (T::*adress)(); // pointer to be accessed by Entry
   
    public:
        Thread(void (T::*functiontocall)());
        ~Thread();
        virtual void* Entry();
};
// ...
Thread<Zentrale> *thread;
etc.

I'm not sure I understand #1. In any case, I don't see any way to remove pointers.
thanks, sounds great, have to try that.
to #1:
I just want to remove the *adress pointer.
Cant I define the pointer functiontocall like i did it with the adress pointer and then use it everywhere in the class? (in the constructor it gets set, and then i use it in Entry..).
possibly there is no way around having two pointers.
20000 kbit/s | 1176 kbit/s | 10ms
NB: M-C2D P9500 | 9800M GTS | 2048 MiB DDR3 | 160 GB | Windows XP SP3
SERVER: XP 2800+ | 1024 MiB DDR-400 | 2*500 GB SATA | Debian 5.0
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

I'm not an expert on function-pointers, but I'm pretty sure what you want can't be done
rodrigod
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Thu Jun 26, 2008 8:50 pm

Post by rodrigod »

Check what I have done to create a class of thread that can point to any functio (as long it only has one parameter)

Code: Select all

#include "stdwx.h"
#include "wxThread.h"


MyThread::MyThread()
        : wxThread()
{

	pt2Function=NULL;		
	pParameter=NULL;
}

void MyThread::Function(UINT (*pt2Func)(LPVOID),LPVOID *pParam)
{
	pt2Func(pParam);
}

void MyThread::OnExit()
{
}

void *MyThread::Entry()
{
	if(&pt2Function!=0 || &pParameter!=0)
		Function(pt2Function,pParameter);

    return NULL;
}
It works very well for me. If any one has any coments on it I would apreciate.

see ya
kmindi
Earned a small fee
Earned a small fee
Posts: 21
Joined: Sun Jan 07, 2007 7:40 pm

Post by kmindi »

rodrigod wrote:Check what I have done to create a class of thread that can point to any functio (as long it only has one parameter)

Code: Select all

#include "stdwx.h"
#include "wxThread.h"


MyThread::MyThread()
        : wxThread()
{

	pt2Function=NULL;		
	pParameter=NULL;
}

void MyThread::Function(UINT (*pt2Func)(LPVOID),LPVOID *pParam)
{
	pt2Func(pParam);
}

void MyThread::OnExit()
{
}

void *MyThread::Entry()
{
	if(&pt2Function!=0 || &pParameter!=0)
		Function(pt2Function,pParameter);

    return NULL;
}
It works very well for me. If any one has any coments on it I would apreciate.

see ya
does this work with a pointer to a member of a specific class?
20000 kbit/s | 1176 kbit/s | 10ms
NB: M-C2D P9500 | 9800M GTS | 2048 MiB DDR3 | 160 GB | Windows XP SP3
SERVER: XP 2800+ | 1024 MiB DDR-400 | 2*500 GB SATA | Debian 5.0
rodrigod
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Thu Jun 26, 2008 8:50 pm

Post by rodrigod »

Actually I only used it as a pointer to a function. Never to a member of a class. But you could try passing (class::function) as a parameter and see if it works. Or you could create a function that calls that class member and pass that function to you thread.

Hope I helped

see ya
Post Reply