How to copy-clone an object ?

I have a function that receives a object instance
and I'd want to copy-clone to an independent inner object instance of the same class.?

1
2
my_function(class_x a_class_x_instance)
my_undo_copy_of_class_x = a_class_x_instance ;


The initial object is pointer based.
How can I define the function and the way I pass and assign the object to have the better performance ? My object is medium-big size (200 M) and it is composed by a struct instance and some vectors of custom structs..

Any help would be appreciated.

What unit of measurement are you using when you write "200 M"? Is it 200 MiB? Are you saying your code handles a single object that costs 200 MiB of RAM? If so, I wouldn't clone it just to implement an undo/redo mechanism.

Still, to answer the question: You just clone whatever you need to clone to obtain a perfect, usable copy of the object. More I cannot say, except maybe that your function should receive the object by reference (your code shows by value). Are you asking because you are worried about copying 200 MiB for something as simple as a change in some minor text? I'd be worried too! This is why I am telling you a redo/undo mechanism has to be more effective than that.

In general, an Undo/Redo engine is based in an interface; a pure virtual class (let's name it IUndoableAction) allows you to maintain a queued collection of actions that can be undone in a LIFO order. Usually IUndoableAction would look something like this:

1
2
3
4
5
6
7
8
class IUndoableAction
{
public:
    virtual std::wstring GetName() = 0;
    virtual bool Undo() = 0;
    virtual bool Redo() = 0;
    virtual ~IUndoableAction() { }
};


In your particular case, I would make my undoable action classes maintain a pointer to the object they apply to instead of cloning the object they apply to.
Ok, Now I'm doing a 'global' undo with a complex 3D object. (Yes, in the future I'm going to implement a better solution).
But now I only want to pass an object an make a copy of it.
Now I have:

1
2
3
4
5
6
ClassX * the_object_undo;
 
void w_set_undo(CLass  the_object)
{ the_object_undo = &the_object }
 
ClassX * w_get_undo(){ return the_object_undo}


I dont know what is happen.
The properties of the_object_undo inside w_set_undo as right, but NOT inside w_get_undo. How to fix it ?

I need help...
Thanks.
You don't seem to be copy/pasting code, and therefore your code samples have problems which make more difficult for me (us) to help you. I'd recommend that you copy/paste working or compilable samples. For example, your class name is ClassX, but the parameter to w_set_undo() is CLass. In this particular example I think I follow, but in other instances, errors like this could throw additional confusion into the discussion.

Now, I see that you are now not cloning/copying the object, you are simply storing the address of an object. The problem here is that w_set_undo() receives the object by value, meaning you are only storing the address of a temporary object. By the time you call w_get_undo(), the pointer is no longer valid.

So at this point I am unsure if this is an actual problem in your working code, or if it is just something you "forgot" to type in.

Bottom line: Receive the object by reference (I have said this twice and you are not complying; do you know how to do this?) in w_set_undo(), then create a copy of the object and store it in the_object_undo. How to create the copy? It depends entirely in the internals of the ClassX class. I cannot tell you how to code a clone/copy constructor or function without knowing exactly what the class contains.
Thanks webjose. You have given me the solution.
Inside set_undo:
1
2
3
4
set_undo(CLassX the_object) {
object_undo = new ClassX() ;  (the object must exist before)
*object_undo =the_object;
}

It seems that works !
What do you think ?
Thanks
Last edited on
You're still getting the object by value and not by reference. You are also making use of the assignment operator (operator=) instead of the more efficient copy constructor.

Buuuuut, in the end, it is up to you. So long it works...
Topic archived. No new replies allowed.