Skip to main content
gamedev.net
🔒 Locked

dynamically setting up virtual function table?

Started by FReY Dec 22, 2005 at 7:02 AM 5 replies 1.5k views
Original Post
FReY
FReY
I'm seeking to expand my C++ education into the little nooks and crannies that have remained out of sight till now... Is there any way of setting up a specific virtual function table on an arbitrary block of memory without using 'new'? Example:

class CBaseObj
{
public:
  virtual void Blah() = 0;
};

class CInheritedObj : public CBaseObj
{
public:
  virtual void Blah()
  {
    printf("inherited");
  }
};
  
void main()
{
  void     *pvMem;
  CBaseObj *psObj;

  // memory may be alloc'd with new/malloc/whatever.
  pvMem = ObtainEnoughMemoryByArbitraryMeans(sizeof(CInheritedObj));

  // clear this just to demonstrate that the vftable was not setup beforehand
  memset(pvMem, 0, sizeof(CInheritedObj));

  // after this call, psObj will have the correct vftable. And it's inherited
  // methods will now be correctly callable. 
  psObj = deploy_vftable_cast<CInheritedObj *>(pvMem);

  // will print 'inherited'
  psObj->Blah();
}


Is there anything analogous to the 'deploy_vftable_cast' that I've used above? With or without RTTI? I thought of using a templated approach and copying the vftable from an instance of the CInheritedObj but I don't really relish this as an option... C++ gurus?
do unto others... and then run like hell.
ToohrVyk
ToohrVyk
No, there is no standard or portable way to do this, although there are obviously hacks that are possible for every compiler (which exploit that particular compiler's output code).

I can't help but believe that, whatever you could try to achieve through this method, there would be a less contrived (and more standard) method available to reach the same ends.
FReY
FReY
Never mind my intentions, it's just for exploration good sir ;)

"placement new" seems to be the key to this. Amazing what a good 'google' will turn up...

http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10
do unto others... and then run like hell.
tj963
tj963
I can't see any useful reason for messing with the vtable either. Like ToohrVyk said, whatever you did would be compiler specific. However, you could create something like a vtable using an array of member function pointers. It's still messy, but I have seen it done.

tj963
tj963
Urxae
Urxae
There's no portable way to put just a vtable somewhere, the C++ standard doesn't even require that vtables are used. It's just the way most (if not all) compilers work.

Assuming you're only talking about compilers that use vtables:

Why do you want to do it without new? Setting up the vtable is (part of) its job.
Since you shouldn't be putting vtables in places that aren't complete objects (including other member variables), placement new is probably closest to what you want to achieve:
psObj = new(pvMem) CInheritedObj;

Note that this also calls the default constructor, and may thus also change other parts of the memory being passed other than the vtable pointer.
For that reason you'll probably want to explicitly call the destructor before you deallocate the memory:
psObj->~CBaseObj();

Excuse me if the syntax isn't entirely correct, this is not something I usually do [wink].

Oh, and you may want to make sure "ObtainEnoughMemoryByArbitraryMeans" returns memory properly aligned for CInheritedObj.

I agree with ToohrVyk, though. There's probably a better way to do whatever you want to do.

EDIT: Bah, too slow.
And you forgot to make the destructor virtual.
FReY
FReY
Well, one can't immediately see the uses of studying most things when you think about it.

I really do understand your guys concerns. I have an inquisitive mind that's all - please do not worry yourself as I am not a programming 'n00b', but I'm just exploring the mechanisms of C++ ;)

I do appreciate your guys input though, so rating++ all around ;)
do unto others... and then run like hell.
ToohrVyk
ToohrVyk
Quote:
Original post by FReY
Is there any way of setting up a specific virtual function table on an arbitrary block of memory without using 'new'?


Quote:
Original post by FReY
"placement new" seems to be the key to this. Amazing what a good 'google' will turn up...


Exactly. Or any other overloaded operator new you decide to use/implement, by the way.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.