Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should an object with a pointer to its parent have a copy constructor defined?

Tags:

c++

If an object A contains a member Object B and Object B has a pointer to its parent Object A, do I need to specify a copy constructor for Object B?

Assume there is no dynamic allocation.

Furthermore, does the rule of 3 apply here?

like image 426
tom1989 Avatar asked Oct 18 '22 18:10

tom1989


1 Answers

Your design implements composition with a bidirectional navigation. This can be perfectly valid.
However, as Sergey pointed out in the comments, such a design is not without problems.

Suppose you have a class Object and a class Container that contains an Object. Here some fundamental questions:

Container c;
Object mo1; // Q1: should this be valid ? (i.e. is an object without parent allowed 
Object mo2 = c.o;  // Q2: is this acceptable ?  Q3: Who is parent of mo2 ?  

Look at questions Q2 and Q3: if such initialization is acceptable, then the immediate question is what parent do you want:

  • if mo2 should have no parent, you need a copy constructor according to rule of 3, to clear the parent.
  • if mo2 should refer to the same parent (although it is not a member), you could keep the default copy constructor.

Example:

struct Container; 
struct Object{
    Container *parent;  
    Object (Container *p=nullptr) : parent(p) { cout << "construct object"<<endl; }
    // copy constructor or compiler generated one depending on Q2+Q3
    ~Object() {}
    ...
};
struct Container {
    Object o;
    Container() : o(this) {}
};

If such initialization is NOT acceptable, you should forbid copy constuction explicitely in the code.

Object (const Object &o) = delete;  

Important note: the Container might also need a copy constructor. Whatever you decide for Object, you might have to deal with in the Container if it has to be copiable. In no way could you use there the copy constructor of the Object.

Important note 2: the Container might itself be used in more complex situations. Take the example of a vector<Container>. When new containers are added to the vector, relocation might be performed, which could invalidate the pointers if you didn't provide a Container copy constructor that takes care !

like image 171
Christophe Avatar answered Nov 15 '22 11:11

Christophe