Zeroing a class with virtual functions

Started by
7 comments, last by Denix Linelli 21 years ago
What is the correct way to zero a class that contains virtual functions? Using ZeroMemory/memset clears __vfptr so all virtual functions cause an access violation. And I don''t want to set all members to zero manually because then I''d have to write a function to do that for every class.
Advertisement
if it just contains a virtual functions, ZeroMemory or memset should not be a problem. But, use the objects instantiated from that class, not the class itself!

// correct
MyClass MyObj;
ZeroMemory( &MyObj, sizeof(MyObj) );

// wrong
MyClass MyObj;
ZeroMemory( &MyClass, sizeof(MyClass) );

If the class contains a pure virtual functions, you can''t use both ZeroMemory and memset. Why? Because you can''t instantiate an object from a class that contains a pure virtual functions. If no object is instantiated, whose memory are we trying to set?

Current project: 2D in Direct3D engine.
% completed: ~20%
The proper way is to write a function that clears each member, especially for classes that manage pointers to data. Depending on what type of states your classes will be in, you might not need to write one for each and every class you have, but that's how it should be done. Technically, you could still use memset on classes without a vtable, however it isn't considered good practice and will probably get you beheaded in many programming circles

If you have an array of your objects, you could use std::fill and pass it a temporary to assign to each object, assuming a newly created temporary is in the state you want your objects to be in. Once again, if you're not working with any pointers to data, the default assignment operator should do what you need, otherwise you have to overload your own.

[edited by - Zipster on March 25, 2003 7:21:14 PM]
If you really want to ZeroMem it, rather than set the variable manually, there is a way.

void *operator new(size_t size, void *mem){return mem;}Bob *myBob;myBob = (Bob *)malloc(sizeof(Bob));memset(myBob, 0, sizeof(Bob));new(myBob) Bob;...myBob->~Bob();free(myBob); 


You could do a regular new, zero it, do the placement new, but then the constructors will be called twice (once for each new).

Bob *myBob;myBob = new Bob;memset(myBob, 0, sizeof(Bob));new(myBob) Bob;...delete myBob; 


The first technique works well for dynamic sized arrays. On resize, if getting smaller, destruct the last n items. realloc(oldptr, newsize); Or if getting larger, realloc(oldptr, newsize); and do placement new on each new item.

You are allowed to zero via memset any PoD type (plain ol'' data type). Class and struct are interchangable (private/public defaults). You can even use a zero memset with class/struct that uses inheritence, so long as it inherits from PoDs.

If a class contains any virtual functions or uses virtual inheritence it is not a PoD. You definetly can have member functions, and I''m pretty sure you can have ctor''s & dtor''s (though there might be a portability issue).
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
The ctor and dtor do not matter i think in the non-POD classes. But since the placement of the vtable in the class memory is not directed by the standard, a standard memset or ZeroMem is not valid. You can overload operator new, which seems the best idea to me, or you can simply zero the data in the constructor.


Gamedev for learning.
libGDN for putting it all together.
An opensource, cross platform, cross API game development library.
VSEDebug Visual Studio.NET Add-In. Enhances debugging in ways never thought possible.
You could always use offsetof in combination with sizeof.
Keys to success: Ability, ambition and opportunity.
The ''normal'' way to initialise the members is in the constructor.
quote:Original post by Magmai Kai Holmlor
You are allowed to zero via memset any PoD type (plain ol' data type).

No you aren't. There's no guarantee given in the C++ Standard that zero value is represented by all-bits-zero. When you go "behind the scenes" and monkey with the bit representations of any value, you potentially sacrifice the type-safety guarantees that the C++ Standard provides. Don't do that!

[edited by - SabreMan on March 26, 2003 11:55:14 AM]

This topic is closed to new replies.

Advertisement