Cast from void* to base class virtual function problem

L

Luke Dalessandro

Code: Thread -> U
-> T

public class Thread {
protected:
thread_t _tid;
virtual void foo() = 0;

public:
// Static entry function for the internal thread
static void* ThreadEntry(void* pThread) {
Thread* thread = static_cast<Thread*>(pThread);

// ***
// *** This is the error, calls the pure virtual version...?
// ***
thread->foo();
return 0;
}

// Starts the internal thread running
void Start() {
pthread_create(&_tid, NULL, Thread::ThreadEntry, this);
}
}

public class T : public Thread {
protected:
virtual void foo() {
cout << "I'm a T";
}
}

public class U : public Thread {
protected:
virtual void foo() {
cout << "I'm a U";
}
}

As you can see I'm just trying to re-use some pthread code for a
multithreaded server that spawns new threads for different reasons. I
can't figure out how to cast the void* to a base Thread* pointer and
call the pure virtual "foo" function and get the derived behavior...

Of course, the standard usage like

Thread* u = new U();
u->foo();

calls the derived foo like I expect.

I also tried a non-pure virtual foo and the Thread::foo is still getting
called after the cast.

I'm on OSX 10.4 development version. Not sure which gcc it is.

Thanks in advance,
Luke
 
G

Greg

Luke said:
Code: Thread -> U
-> T

public class Thread {
protected:
thread_t _tid;
virtual void foo() = 0;

public:
// Static entry function for the internal thread
static void* ThreadEntry(void* pThread) {
Thread* thread = static_cast<Thread*>(pThread);

// ***
// *** This is the error, calls the pure virtual version...?
// ***
thread->foo();
return 0;
}

// Starts the internal thread running
void Start() {
pthread_create(&_tid, NULL, Thread::ThreadEntry, this);
}
}

public class T : public Thread {
protected:
virtual void foo() {
cout << "I'm a T";
}
}

public class U : public Thread {
protected:
virtual void foo() {
cout << "I'm a U";
}
}

As you can see I'm just trying to re-use some pthread code for a
multithreaded server that spawns new threads for different reasons. I
can't figure out how to cast the void* to a base Thread* pointer and
call the pure virtual "foo" function and get the derived behavior...

Of course, the standard usage like

Thread* u = new U();
u->foo();

calls the derived foo like I expect.

I also tried a non-pure virtual foo and the Thread::foo is still getting
called after the cast.

I'm on OSX 10.4 development version. Not sure which gcc it is.

Thanks in advance,
Luke

The code that allocates the Thread object for each pthread created is
missing from your post. In fact there is no obvious execution order to
the code that was posted.

Without knowing what pThread is actually pointing to, it's not possible
to fully diagnose the problem. It's also possible that there is no code
in the program to create new Thread objects, in which case the same
pThread pointer is being passed to every pthread.

Greg
 
A

Axter

Luke said:
Code: Thread -> U
-> T

public class Thread {
protected:
thread_t _tid;
virtual void foo() = 0;

public:
// Static entry function for the internal thread
static void* ThreadEntry(void* pThread) {
Thread* thread = static_cast<Thread*>(pThread);

// ***
// *** This is the error, calls the pure virtual version...?
// ***
thread->foo();
return 0;
}

// Starts the internal thread running
void Start() {
pthread_create(&_tid, NULL, Thread::ThreadEntry, this);
}
}

public class T : public Thread {
protected:
virtual void foo() {
cout << "I'm a T";
}
}

public class U : public Thread {
protected:
virtual void foo() {
cout << "I'm a U";
}
}

As you can see I'm just trying to re-use some pthread code for a
multithreaded server that spawns new threads for different reasons. I
can't figure out how to cast the void* to a base Thread* pointer and
call the pure virtual "foo" function and get the derived behavior...

Of course, the standard usage like

Thread* u = new U();
u->foo();

calls the derived foo like I expect.

I also tried a non-pure virtual foo and the Thread::foo is still getting
called after the cast.

I'm on OSX 10.4 development version. Not sure which gcc it is.

Thanks in advance,
Luke

In C++, you don't put key word public before a class declaration.
 
L

Luke Dalessandro

Greg said:
The code that allocates the Thread object for each pthread created is
missing from your post. In fact there is no obvious execution order to
the code that was posted.

Without knowing what pThread is actually pointing to, it's not possible
to fully diagnose the problem. It's also possible that there is no code
in the program to create new Thread objects, in which case the same
pThread pointer is being passed to every pthread.

Greg

Greg,

Sorry about the lack, I was trying to remove everything that didn't seem
necessary. The code is basically:

int main (int argc, const * char argv[]) {

string toExit;
Thread* t;

while (toExit != "exit") {

cin >> toExit;

if (toExit = "U") {
t = new U();
}
else {
t = new V();
}

t->Start();

delete t;

}

}

Constructors are:

Thread::Thread() {}
U::U() {}
V::V() {}

Destructors are:

virtual ~Thread() {}
virtual ~U() {}
virtual ~V() {}

I realize that the main thread s pulling the rug out from under the
pthreads that are running inside the Thread objects... I'm actually
storing the pointers somewhere and joining and deleting threads elsewhere.

Luke
 
L

Luke Dalessandro

Axter said:
In C++, you don't put key word public before a class declaration.

Lol... you're right... I've been stuck in C# land for too long (language
at work). Thanks for pointing that out... I didn't cut and paste the
code, I just re-wrote it in simplified form, so there was no compiler
around to yell at men.

Luke
 
L

Luke Dalessandro

Luke said:
The code that allocates the Thread object for each pthread created is
missing from your post. In fact there is no obvious execution order to
the code that was posted.

Without knowing what pThread is actually pointing to, it's not possible
to fully diagnose the problem. It's also possible that there is no code
in the program to create new Thread objects, in which case the same
pThread pointer is being passed to every pthread.

Greg

Greg,

Sorry about the lack, I was trying to remove everything that didn't seem
necessary. The code is basically:

int main (int argc, const * char argv[]) {

string toExit;
Thread* t;

while (toExit != "exit") {

cin >> toExit;

if (toExit = "U") {
t = new U();
}
else {
t = new V();
}

t->Start();

delete t;

}

}

Constructors are:

Thread::Thread() {}
U::U() {}
V::V() {}

Destructors are:

virtual ~Thread() {}
virtual ~U() {}
virtual ~V() {}

I realize that the main thread s pulling the rug out from under the
pthreads that are running inside the Thread objects... I'm actually
storing the pointers somewhere and joining and deleting threads elsewhere.

Luke

Sigh...

I think I solved my own problem. I really was deleting the Thread object
while it's internal thread was still running. This was causing the "pure
virtual function call" because "this" (passed as a void*) had actually
been deleted, so casting it to a Thread didn't cast it to a U or a V.

If I'm more careful about the delete call, ie joining first or
something, it works fine. Multithreading gets me again...

Sorry to bother everyone.

Luke
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top