Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Cast from void* to base class virtual function problem

Reply
Thread Tools

Cast from void* to base class virtual function problem

 
 
Luke Dalessandro
Guest
Posts: n/a
 
      09-18-2005
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
 
Reply With Quote
 
 
 
 
Greg
Guest
Posts: n/a
 
      09-18-2005

Luke Dalessandro wrote:
> 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

 
Reply With Quote
 
 
 
 
Axter
Guest
Posts: n/a
 
      09-18-2005

Luke Dalessandro wrote:
> 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.

 
Reply With Quote
 
Luke Dalessandro
Guest
Posts: n/a
 
      09-18-2005


Greg wrote:
> Luke Dalessandro wrote:
>
>>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
>


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
 
Reply With Quote
 
Luke Dalessandro
Guest
Posts: n/a
 
      09-18-2005


Axter wrote:
> Luke Dalessandro wrote:
>
>>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.
>


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
 
Reply With Quote
 
Luke Dalessandro
Guest
Posts: n/a
 
      09-18-2005


Luke Dalessandro wrote:
>
>
> Greg wrote:
>
>> Luke Dalessandro wrote:
>>
>>> 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
>>

>
> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Why polymorph fails when virtual function is decleared private in base class and public in derived class? Fred C++ 2 06-03-2007 02:59 PM
calling virtual function results in calling function of base class... Andreas Lagemann C++ 8 01-10-2005 11:03 PM
calling virtual function results in calling function of base class ... tiwy C++ 0 01-09-2005 11:17 PM
Virtual function 'BasicMidReader::~BasicMidReader()' conflicts with base class 'base 'TMemoryStream' tomek C++ 2 12-01-2003 06:31 AM
Virtual function 'BasicMidReader::~BasicMidReader()' conflicts with base class 'base 'TMemoryStream' tomek C++ 3 11-30-2003 12:18 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57