473,324 Members | 2,254 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,324 software developers and data experts.

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
Sep 18 '05 #1
5 2975

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

Sep 18 '05 #2

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.

Sep 18 '05 #3


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
Sep 18 '05 #4


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
Sep 18 '05 #5


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
Sep 18 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: tirath | last post by:
Hi all, I have a templated class that derives from a non-templated abstract class. How do I then cast a base class pointer to a <templated> derived class pointer in a generalised fashion? ...
6
by: Jordi Vilar | last post by:
Hi All, Is there a way to dynamic_cast a pointer to a type defined by a type_info*? something like: type_info *info_of_type_to_cast = typeid(type_to_cast); type_to_cast *casted =...
6
by: Eric Lilja | last post by:
Hello, I have a std::vector storing pointers to an abstract base class OptionBase. OptionBase is not templated but I am deriving a template class called Option from OptionBase. The class Option has...
5
by: Nick Flandry | last post by:
I'm running into an Invalid Cast Exception on an ASP.NET application that runs fine in my development environment (Win2K server running IIS 5) and a test environment (also Win2K server running IIS...
18
by: mark | last post by:
class SORef {...}; class SelectedFORef : public SORef {...}; SOFORef SOCastToSOF(SORef sor) { SelectedFORef sof=nil; sof=dynamic_cast<SelectedFORef>(sor); return sof; };
7
by: WaterWalk | last post by:
Hello. I thought I understood member function pointers, but in fact I don't. Consider the following example: class Base { public: virtual ~Base() {} }; class Derived : public Base {
6
by: alan | last post by:
I'm creating a sort-of "wrapper" class which (partly) acts like a variable. Something like: template<class t> class cell{ t curval; public: /*public for debugging only - will be private in...
9
by: jason.cipriani | last post by:
All right, I'm in this weird situation that's hard to explain but I've put together a small example program that represents it. Please bear with the fact that some of the stuff in the example seems...
2
by: Lenin | last post by:
Hi, I have a multiply inherited class "C" as folloows. None of them are inherited as virtual base class except that they have virtual functions. class b1 { .... virtual void f1() {} }
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.