LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   casting void* to an abstract class (https://www.linuxquestions.org/questions/programming-9/casting-void%2A-to-an-abstract-class-510673/)

qwijibow 12-15-2006 07:38 AM

casting void* to an abstract class
 
Hello...

Just For Fun... Im Writing a small Game Engine Based on SDL, and im having loads of trouble trying to write a Thead abstract class.

I'm at work at the moment, and dont have access to my code, but the design is like so....


Code:

class IThread
{
public:
    virtual void Main(void)=0;

    void Start(IThead *This);
};

int ThreadStarter(void *thread)
{
    if(thread!=NULL)
    {
        IThread *Thread = reinterpret_cast<IThread*>(Thread);
        Thread->Main();
    }
}


void IThread::Start(IThread* This)
{
    SDL_CreateThread(ThreadStarter, This);
}


I Then Inherit From The IThread Class to create my Background Thread, The Background Thread Implements the virtual Main() of IThread, and calls Start with the this pointer as a parameter.

My Problem is, The ThreadStarter's Call to main Always attempts to run the Virtual Main, Not The Background threads Main().

Whats Going Wrong ???

I Assume the reinterpret_cast is messing up the vtable ???

But How Else Can i Cast a void pointer to an IThread ???

Can Anyone point out is wrong / how to fix it ?
or surgest a better way of implementing a thread class with SDL ???

Thanks !

bigqueso 12-15-2006 11:04 AM

This code seems to work for me on cygwin and Suse 9.3. One thing you might try is to change the name of Thread to thread. There might be some funniness going on otherwise.

IThread *Thread = reinterpret_cast<IThread*>(Thread);

to

IThread *Thread = reinterpret_cast<IThread*>(thread);


Code:

#include <iostream>

using namespace std;

class IThread
{
public:
  virtual ~IThread() {}
  virtual void Main(void) { cout << "IThread\n"; }
};

class Background: public IThread {
public:
  virtual void Main(void) { cout << "Background\n"; }
};

int ThreadStarter(void *thread)
{
  if(thread!=NULL)
    {
      IThread *Thread = reinterpret_cast<IThread*>(thread);
      Thread->Main();
    }
  return 0;
}


int main()
{

  Background background;

  ThreadStarter((void*)&background);

  return 0;
}

James

qwijibow 12-15-2006 03:55 PM

Solved.......
Although im not quite sure why.

I Origonaly had the SDL_CreateThread() in the contructor of IThread.
This apears not to work... Although im not quite sure why....

Maybe Because IThread's Constructor was running Before CBackground's Main() was added to the vtable... ?

Compiler Bug ????

Anyways, thanks.

ta0kira 12-23-2006 08:43 PM

Unless the original pointer was static_cast to IThread* before casting to void*, you are lucky the code ended up working. Technically void* only has to cast back to the same type it was cast from originally. It isn't really a cast, however; it's just a loophole in C++ allowing you to disregard the type of the pointer to make something compile. If the pointer was to an object derived from IThread, the IThread* value might not be the same as 'this'. Real casting entirely depends on how the compiler sees pointers at the time of the cast; if it sees you are casting A to B it knows (because it decides) what offset in value that cast might have. When casting to/from void*, C-casting, or reinterpret_cast'ing you (or someone else) are making a hole in the program for some convenience or another. Casting from void* does absolutely nothing, meaning if you cast A to void* then to B, you are saying that there is a B located where the A really is, which is not required to be true. Normally if B is the first base class of A this is not a problem, however, which is probably why it worked for you afterall.
ta0kira


All times are GMT -5. The time now is 06:55 PM.