Jump to content
  • Advertisement
Gnollrunner

C++ Size of C++ polymorphic objects.

Recommended Posts

I already asked this question on stack overflow, and they got pissed at me, down-voted me and so forth, LOL .... so I'm pretty sure the answer is NO, but I'll try again here anyway just in case..... Is there any way to get the size of a polymorphic object at run-time? I know you can create a virtual function that returns size and overload it for each child class, but I'm trying to avoid that since (a) it takes a virtual function call and I want it to be fast and (b) it's a pain to have to include the size function for every subclass. I figure since each object has a v-table their should be some way since the information is there, but perhaps there is no portable way to do it.

Share this post


Link to post
Share on other sites
Advertisement
Posted (edited)

If by "polymorphic object", you mean "derived type but using a base type pointer", then no, of course you can't get that without virtual function dispatch or a dynamic_cast.  C++ has no way of knowing which type you actually want the size of, even with RTTI.  Therefore, you either have to tell it, either directly (through dynamic_cast), or indirectly (through providing the plumbing in the virtual interface).

Edited by SeraphLance

Share this post


Link to post
Share on other sites

I mean an instantiated object of a class with a virtual function..... A common case which I imagine could be implemented without too many problems is simply some operator/function that returns the size of the full object in memory.   Seems like they are mucking with the language all the time so I was hoping there was some new way to do it but I guess not.

Share this post


Link to post
Share on other sites
5 minutes ago, Gnollrunner said:

Seems like they are mucking with the language all the time so I was hoping there was some new way to do it but I guess not.

C++ pseudo-operator sizeof works at compile time, not at runtime, so it unable to determine size of object that exact type is unknown at compile time. So only way  to get size of object at runtime is a virtual method.

9 hours ago, Gnollrunner said:

I already asked this question on stack overflow, and they got pissed at me, down-voted me and so forth, LOL ....

it really "must know after first lecture" question about C and C++ 

Share this post


Link to post
Share on other sites
9 hours ago, Gnollrunner said:

 I figure since each object has a v-table their should be some way since the information is there, but perhaps there is no portable way to do it.

Each polymorphic object with have a vtable, but at runtime the code wont know anything about it other than that the vtable is there and where to go get those functions.  That's how it works, it just calls whatever is in the vtable for each function.  So while the knowledge about the object type is there during compile, it doesnt get added to objects such that it can be accessed during runtime.  

Share this post


Link to post
Share on other sites
Posted (edited)

This is such an odd question, I feel like it must be you having a different problem, thinking of (but not really) having the solution which you "just" need the size of the objects for. If you need to ask a polymorphic object which type it is, you are most likely on the wrong way. Also I imagine you wanting the size to copy around the objects manually, which is a bad thing to do.

You better tell what the original problem was, which you are trying to fix!

 

Edited by wintertime

Share this post


Link to post
Share on other sites
54 minutes ago, wintertime said:

If you need to ask a polymorphic object which type it is, you are most likely on the wrong way.

Yeah, this. It's a very strong hint that polymorphism is the wrong tool for your actual situation. If you tell us about the larger scale problem (of which needing to know object sizes is a sub-problem of) there's probably some much better architectures you could be using. 

That said, the most straightforward / simple solution to your actual question (besides a virtual Size method) is to put a public const int size member in the base class, and force every derived type to pass their size to the base's constructor. 

Share this post


Link to post
Share on other sites
49 minutes ago, Hodgman said:

That said, the most straightforward / simple solution to your actual question (besides a virtual Size method) is to put a public const int size member in the base class, and force every derived type to pass their size to the base's constructor. 

Actually I do something like this now but I was trying to save the space. The only thing I need it for is deallocation.  This is for a specialized heap that uses 32 bit 8 byte aligned addresses, where all objects are derived from the same virtual class. I need the size to determine which free list the object goes in when it's deallocated.   It works now, it just seems like storing the size is a waste since all objects are virtual and theoretically the information could be stored with the vtable. In any case I don't really have to pass the size in since I can cheat and set the size in the new operator since I have to create a placement new anyway.

Share this post


Link to post
Share on other sites
1 hour ago, Gnollrunner said:

I need the size to determine which free list the object goes in when it's deallocated

Is this the kind of allocator where you make pools for different sizes (e.g. a pool for <24 byte objects, a pool for <32 byte objects, etc)? If the pools themselves are a contiguous block of memory, then you can probably fairly quickly determine which pool an object was allocated from by the address.
e.g. 

//init a 1KB pool for 24B objects, and another for 32B objects
int poolSize = 1024;
int numPools = 2;
char* mem = malloc(poolSize*numPools);

char* begin24 = mem
int   capacity24 = poolSize / 24;
char* end24 = mem + capacity24 * 24;

char* begin32 = mem
int   capacity32 = poolSize / 32;
char* end32 = mem + capacity32 * 32;

//which pool is an object in?
void* object = ...
ptrdiff_t memOffset = object - mem;
int poolIndex = memOffset / poolSize; // 0 = 24B pool, 1 = 32B pool

 

Share this post


Link to post
Share on other sites
5 hours ago, Hodgman said:

Is this the kind of allocator where you make pools for different sizes (e.g. a pool for <24 byte objects, a pool for <32 byte objects, etc)?

Sort of, but objects in the pools are interleaved randomly so I can't count on a specific range of memory locations for a given object. I'm using the Windows VirtualAlloc function to reserve an address range of 16 gig. Then I commit actual pages of memory as I need them. In any case I think I'll just stick with the size field for now and later I can try the virtual Size function thing and profile it to see what the speed difference is.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!