Archived

This topic is now archived and is closed to further replies.

Zeroing a class with virtual functions

This topic is 5375 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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%

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites