I have a C++ class that contains objects that have reference members pointing to other objects within the class. This seemed like a good idea at the time, but now I need to implement a deep copy of the whole thing, and I can't see a way to do that that doesn't feel like a clunky hack.
A simplified version of my code looks like this. The question is about writing a copy constructor for A
.
class C {
int x, y, z; // nothing complicated stored in this class
public:
// constructor and other methods
};
class B {
C &c1;
C &c2;
public:
// constructor and other methods
};
class A {
C *c_array;
B *b_array; // for each item in this array,
// its 'c1' and 'c2' fields point to members of c_array.
public:
// constructor and other methods
};
A few people have asked how this structure is initialised, so please let me stress that this is irrelevant for answering the question. The initialisation will always satisfy the requirement that the reference members of the items in b_array
point to items in c_array
, but beyond that the data could be anything. It is important that the copy constructor work for any data that satisfies this property. This is not a problem that can be solved by reusing the existing initialisation code.
The problem is that if I just copy the objects in b_array
, their reference members will point to the C
objects in the old instance of A
. I need to make them point to the corresponding items in the new instance. The only way I can think to do that is this:
for each element of
b_array
, get the address that its reference member points to, and store that in a pointerwork out the index into the array that that pointer corresponds to using pointer arithmetic
use this index to initialise the reference member of the corresponding element of the new
b_array
.
My question is, is there a cleaner / simpler / more elegant way? If there isn't, I will just refactor my design to use array indices instead of references throughout.
Perhaps I shouldn't have used reference members - I know some people say it's always better to use pointers. If I had used pointers instead of references, would there be a better solution to this problem? (I can't see one but I don't know.)