Memory allocation in changing a struct to a class...

Started by
3 comments, last by Zahlman 16 years, 3 months ago
So, I've been playing around with optimizing some older code (in c++ / DirectX 9), and came across a bunch of struct statements that I had for vertex types, and each one of them shared some common attributes (an x/y/z for the vertex, and a method to get the size of the struct...) - so, doing the logical (in my mind...) thing, I decided to simplify some things by creating a base class with common attributes and deriving the other vertex types from that base class... which in turn would eliminate a lot of (almost) duplicate functions for setting up vertex buffers, etc... so essentially, I went from the following example (simplified for illustration):

struct SingleVertNoColor {
  float x, y, z;
  size_t getSize() { return sizeof(SingleVertNoColor); }
}
struct SingleVertWithColor {
  float x, y, z;
  int32 color;
  size_t getSize() { return sizeof(SingleVertWithColor); }
}

... to the following code:

class IVertexType {
public:
  float x, y, z;
  virtual size_t getSize()=0;
}

class SingleVertNoColor : public IVertexType {
public:
  virtual size_t getSize() { return sizeof(SingleVertNoColor); }
}

class SingleVertWithColor : public IVertexType {
public:
  int32 color;
  virtual size_t getSize() { return sizeof(SingleVertWithColor ); }
}


Now... in the struct versions, the sizeof(SingleVertNoColor) is 12 and sizeof(SingleVertWithColor) is 16 (which is expected...). In the class versions, of course, there is the overhead of the _vftable, so the sizeof(SingleVertNoColor) becomes 16 and sizeof(SingleVertWithColor) jumps to 20. Now, this isn't a problem, however, when I go to lock and copy my vertices into my LPDIRECT3DVERTEXBUFFER9, the extra size is no problem, but it always seems to want to put the _vtable pointer at the beginning of the memory space for the derived classes... Is there any way to tell the compiler to push all member variables to the front of the classes' memory allocation, or, since I'm using customized D3DVERTEXELEMENT9 items for declaring my vertexes (i.e. non-FVF), is there any way to add in the extra _vftable pointer (and have it's usage be set to ignore / nothing)? Or - even with the second thought, would I even be guaranteed that my class items would even be in the same order? Any thoughts? Much appreciated in advance.
Advertisement
Here are some sites that might have what you're looking for:

MSDN Article

Article about vftables

The latter looks like it has what you're looking for. I'd elaborate, but I'm too sleepy to make sense of it at the moment :)
I do real things with imaginary numbers
I'd be surprised if you could change the position of the vtable pointer. The simplest solution would be to change the code to not require virtual functions, but that might not be very useful.

You should be able to change the offset of all of your vertex type declarations so that the first element (position, probably) starts at offset 4 instead of 0, but I'm not sure if D3D will spit warnings out at you for doing that (You are using the debug runtimes, right?)
Quote:Original post by Evil Steve
You should be able to change the offset of all of your vertex type declarations so that the first element (position, probably) starts at offset 4 instead of 0, but I'm not sure if D3D will spit warnings out at you for doing that (You are using the debug runtimes, right?)


Ah, yes - that would be the most easy solution to try... and that worked out perfectly... and yes - debug runtimes are my friend... ;)

That article about vtables was nice - thanks for the reference...

Thanks both - rate++!


That kind of thing is incredibly hacky and non-portable. The way virtual functions work is totally implementation defined. "vtable" is not in the Standard's vocabulary.

If you didn't need polymorphism before, you probably don't need it now. That means there is no obvious reason for making anything virtual. (Chances are good that a .getSize() function doesn't make any sense here either, because if you didn't need polymorphism before, it's because you always knew the exact type, and if you know the exact type, you can just use sizeof() directly.)

Anyway, 'class' and 'struct' only differ, in C++, in terms of default "protection" (public vs private) of members (including bases). You can certainly inherit or even put virtual functions into a struct, or make a class that is a "POD struct" (only somewhat strangely, the term "POD class" seems not to exist in the literature).

class SingleVertNoColor { float x, y, z; };class SingleVertWithColor : SingleVertNoColor { int32 color; }

This topic is closed to new replies.

Advertisement