Let's say I have two object types, A and B. The relationship between them is many-to-many, but neither of them is the owner of the other.
Both A and B instances need to be aware of the connection; it's not just one way.
So, we can do this:
class A
{
...
private: std::vector<B *> Bs;
}
class B
{
private: std::vector<A *> As;
}
My question is: where do I put the functions to create and destroy the connections?
Should it be A::Attach(B), which then updates A::Bs and B::As vectors?
Or should it be B::Attach(A), which seems equally reasonable.
Neither of those feels right. If I stop working with the code, and come back after a week, I'm sure I won't be able to recall if I should be doing A.Attach(B) or B.Attach(A).
Perhaps it should be a function like this:
CreateConnection(A, B);
But making a global function seems undesirable also, given that it's a function specifically for working with only classes A and B.
Another question: if I run into this problem/requirement often, can I somehow make a general solution for it? Perhaps a TwoWayConnection class that I can derive from or use within classes that share this type of relationship?
What are some good ways to handle this situation… I know how to handle the one-to-many "C owns D" situation quite well, but this one is trickier.
Edit: Just to make it more explicit, this question doesn't involve ownership issues. Both A and B are owned by some other object Z, and Z takes care of all ownership issues. I'm only interested in how to create/remove the many-to-many links between A and B.
Best Answer
One way is to add a public
Attach()
method and also a protectedAttachWithoutReciprocating()
method to each class. MakeA
andB
mutual friends so that theirAttach()
methods can call the other'sAttachWithoutReciprocating()
:If you implement similar methods for
B
, you won't have to remember which class to callAttach()
on.I'm sure you could wrap that behavior up in a
MutuallyAttachable
class that bothA
andB
inherit from, thus avoiding repeating yourself and scoring bonus points on Judgement Day. But even the unsophisticated implement-it-in-both-places approach will get the job done.