Right, that's good to have.
(Actually, I didn't even notice that you didn't have a destructor. :p)
What I was saying was more about something to think about as you design your classes/program, and not a particular rule. There are wrong answers (e.g. deleting something with automatic storage), but there is not always one single, right answer. Passing a pointer from the outside into your class, from a point of syntax alone, is ambiguous, because it doesn't establish who now owns that pointer, and the memory it points to. So something extra is needed, such as external knowledge from documentation. Some libraries have attempted to reduce this ambiguity through concepts such as the Guideline Support Library's gsl::owner<T*> [I personally have only seen it used in talks; but just putting that out there if you want to search it up on your own.]
Your design isn't wrong, it's just that the
user of your class needs to be sure they don't do something like
1 2 3 4 5
|
{
Parent parent;
Child child{1};
parent.setChild(&child);
}
|
Libraries like wxWidgets do something similar - they expect items to be allocated with new in order to do proper memory cleanup when a child widget is destroyed (the user doesn't usually call delete themselves).
An alternative that might work, or may not, depending on the use cases of your classes, is to avoid having the end user create the child objects/pointers directly to begin with. For example, you might have something like the following, where all the children are owned by the parent, and the user only indirectly creates a Child by calling "create_child". Again, just brainstorming ideas; I'm not saying "do this".
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
class Parent
{
void create_child(int id)
{
children.push_back(Child{id});
}
void set_active_child(int id)
{
for (Child& child : children)
{
if (child.id == id)
{
active_child = &child;
break;
}
}
}
vector<Child> children;
Child* active_child = nullptr;
};
|