I was wondering whether you think the following code usually indicates a bad design …
class X
{
public:
...
private:
Y y;
};
Class Y
{
public:
Y( X& value ){ x = value; };
private:
X& x;
}
(i.e. there is some sort of cyclic dependency between the classes X and Y).
No, I don’t think it is bad design. It looks like a parent-child relationship (which is 1-to-1) where the child has a pointer back to the parent.
The main reason for such a design is if someone could get a reference to
Ywithout coming throughX. If all access toYare done only throughX, such a reference is more questionable.As Billy ONeal points out, one example could be an iterator that needs to be able to reference the collection it belongs to. This could make it possible to have an iterator into an array that doesn’t need to be invalidated when the array is resized, as it would check the array’s current buffer address and current size on each access.
Another example could be an
OrderLineclass (yourX) which holds a reference to the item and a quantity count etc. It also has an optional member of typeDigitalLicense(yourY).DigitalLicensecontains a large encrypted description of the license, so it’s only included in thoseOrderLinesthat corresponds to a product with a digital license.On construction, a reference to the
DigitalLicenseis also put in a separate map, keyed on the license id. It is now possible to look up aDigitalLicensebased on the license id in the map. Then the back reference is used to go from theDigitalLicenseto theOrderLine. If theOrderLinehas a similar back reference it is possible to get back to theOrderas well.