Apologies if this has been asked before, I'm not quite sure of the terminology or how to ask the question.
I'm wondering if there are libraries or best practices for implementing object models in C++. If I have a set of classes where instances of these classes can have relations to each other and can be accessed from each other via various methods, I want to pick a good set of underlying data structures to manage these instances and their inter-relationships. This is easy in Java since it handles the memory allocation and garbage collection for me, but in C++ I have to do that myself.
HTML's Document Object Model (DOM) is one example; as another (contrived) example, suppose I have these classes:
Entity
Person
(subclass ofEntity
)Couple
(subclass ofEntity
)Property
House
(subclass ofProperty
)Pet
(subclass ofProperty
)Car
(subclass ofProperty
)
and these relationships:
Entity
- has 1
home
of classHouse
- has 0 or more
pets
of classPet
- has 0 or more
cars
of classCar
- has 0 or more
children
of classPerson
- has 1
Person
- has 0 or 1
spouse
of classPerson
- has 0 or 1
marriage
of classCouple
- has 0 or 1
parents
of classEntity
(in this model parents don't exist if they're not alive!)
- has 0 or 1
Couple
- has 2
members
of classPerson
- has 2
Property
- has 1
owner
of classEntity
- has 1
Now that I've thought out these objects and their relationships, I want to start making data structures and methods and fields to handle them, and here's where I get lost, since I have to deal with memory allocation and lifetime management and all that stuff. You can run into problems like the following: I might want to put an object into a std::map
or a std::vector
, but if I do that, I can't store pointers to those objects since they can be relocated when the map or vector grows or shrinks.
One approach I used when I was working with COM a lot, is to have a hidden collection that contained everything. Each object in the collection had a unique ID (either a number or name), by which it could be looked up from the collection, and each object had a pointer to the collection. That way, if you have an object which wants to point to another object, instead of literally holding a pointer to another object, I store the ID and can look it up via the hidden collection. I can use reference-counting to automatically deal with lifetime issues (except for the case of disjoint cycles, sometimes that's not a problem).
Are there other approaches? Or are there libraries to make this kind of stuff easier in C++?
edit: then you have other issues, such as the relationships between objects are likely to be mutable in many cases, and you have to think ahead about how references to objects should be stored, and what methods should be provided for accessing objects from each other. For example, if I have a handle to a Person
X, and I want to represent the concept of "find X's child named George", then I have to store the name "George" rather than a child number: the children may be stored in a vector, and I may be able to call X.getChildCount() and X.getChild(0), but "George" may not always be child number 0, since other children may be inserted before "George" in the child vector. Or X may have two or three or four other children also named "George". Or "George" may change his name to "Anthony" or "Georgina". In all these cases it is probably better to use some kind of unique immutable ID.
edit 2: (and I'll clean up my question a bit once I get this straightened out) I can deal with the choice of methods and property names, I can deal with whether to use a map or a list or a vector. That's fairly straightforward. The problems I'm trying to deal with specifically are:
- how to have one object store a reference to another object, when those objects may be part of data structures that are reallocated
- how to deal with object lifetime management, when there are reciprocal relationships between objects