1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | struct Thing0 { DynamArray arr{}; } struct Thing1 { Thing0 thing0; } struct Thing2 { Thing1 thing1; } Thing2 thing; Thing2 otherThing = thing; //oops! shallow copy performed! //Needed to do this instead Thing2 otherThing; CopyThing(&otherThing, thing); |
mrmixer
My two cents: I think that most of the time, I want a POD (Plain Old Data) copy and when I need to get a "deep copy" I want to be explicit about it (e.g. I need to have a reason for allocating memory and copy the data). So the problem of modifying the wrong data never really occurs or is easy enough to spot. I only use C and the "default is POD copy, be explicit for deep copy" way seem to just flow and fit together well.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | struct DynamArray { DynamArray() { elements = Allocate(4000); } //some other stuff void* elements; } struct Thing0 { DynamArray arr{}; } struct Thing1 { Thing0 thing0; } struct Thing2 { Thing1 thing1; } Thing2 originalThing; Thing2 newThing; CopyArr(&newThing.thing0.arr, originalThing.thing0.arr); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | typedef struct dyn_array_t {…} dyn_array_t; void dyn_array_initialize( dyn_array_t* array, … ) {…} void dyn_array_copy( dyn_array_t* from, dyn_array_t* to ) {…} typedef struct thing_t { dyn_array_t array; … } thing_t; void thing_initialize( thing_t* thing ) { dyn_array_initialize( &thing->array, … ); … } Thing a, b; thing_initialize( &a ); b = a; dyn_array_copy( &a->array, &b->array ); |