Cast from void* to base class virtual function problem | | |
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 | | | | re: Cast from void* to base class virtual function problem
Luke Dalessandro wrote:[color=blue]
> 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";
> }
> }[/color]
[color=blue]
> 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[/color]
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 | | | | re: Cast from void* to base class virtual function problem
Luke Dalessandro wrote:[color=blue]
> 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[/color]
In C++, you don't put key word public before a class declaration. | | | | re: Cast from void* to base class virtual function problem
Greg wrote:[color=blue]
> Luke Dalessandro wrote:
>[color=green]
>>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";
>> }
>>}[/color]
>
>
>[color=green]
>>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[/color]
>
>
> 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
>[/color]
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 | | | | re: Cast from void* to base class virtual function problem
Axter wrote:[color=blue]
> Luke Dalessandro wrote:
>[color=green]
>>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[/color]
>
>
> In C++, you don't put key word public before a class declaration.
>[/color]
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 | | | | re: Cast from void* to base class virtual function problem
Luke Dalessandro wrote:[color=blue]
>
>
> Greg wrote:
>[color=green]
>> Luke Dalessandro wrote:
>>[color=darkred]
>>> 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";
>>> }
>>> }[/color]
>>
>>
>>
>>[color=darkred]
>>> 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[/color]
>>
>>
>>
>> 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
>>[/color]
>
> 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[/color]
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 |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,510 network members.
|