If the sole existence of the animals
object depend on the MyClass
object, then use containment:
class MyClass
{
public:
MyClass();
private:
Animals animals;
};
If the existence of animals
is independent, but MyClass
want to maintain an association to it, then use pointer:
class MyClass
{
public:
MyClass();
private:
Animals * animals;
};
The choice depends on the object ownership model.
There are many considerations involved.
In the containment approach, the memory for animals
is allocated along with the MyClass
object. They always go together and MyClass
fully owns animals
.
In the pointer approach, they are two separate pieces of memory and need to be allocated separately. It is an association without any ownership. Throughout the lifetime of MyClass
, multiple things may happen:
myclass
does not associate to any Animals
, i.e. animals = nullptr
myclass
may associate to different Animals
at different time, i.e. animals = a1; /* ... */; animals = a2;
Moreover multiple objects, either MyClass
objects or other type of objects, may hold the same
animals` pointer.
If the animals
object is destroyed, then these objects have a risk of using the stale pointer, hence some mechanism is necessary to avoid that.
With pointer approach, one can use run time polymorphism which is not possible in the containment approach. For example
void MyClass::setAnimal(Animal * a) {
animal = a;
}
Animal * a1 = new Lion;
Animal * a2 = new Tiger;
MyClass x1;
x1.setAnimal(a1);
MyClass x2;
x2.setAnimal(a2);