Do you want to take the snapshot of the objects externally or you are prepared to alter the classes to support your "undo" infrastructure internally? Just something to consider.
I recently read something in the standard that may be relevant to you. The following code snippets are taken from there:
1 2 3 4 5 6 7
|
#define N sizeof(T)
char buf[N];
T obj; // obj initialized to its original value
std::memcpy(buf, &obj, N); // between these two calls to std::memcpy,
// obj might be modified
std::memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar type
// holds its original value
|
, meaning that you can make snapshots of objects and restore them later. And the second:
1 2 3 4 5 6
|
T* t1p;
T* t2p;
// provided that t2p points to an initialized object ...
std::memcpy(t1p, t2p, sizeof(T));
// at this point, every subobject of trivially copyable type in *t1p contains
// the same value as the corresponding subobject in *t2p
|
, meaning that bit-wise copy can be used to assign the objects.
However, this only applies for classes without complex structure. Self contained, with no references, no pointers, etc. If the object's state is interconnected with the rest of the system, binary snapshot is not enough.
The functions and static member variables are not part of the object data. This is class information. Additionally, virtual functions (if present in the class) require 4 bytes of additional memory in each object (single penalty for the entire set of such functions), few times that if there is multiple inheritance, and about 4 more bytes for each virtual base of the class.