In most cases, it makes sense to use an object instead of pointers. However, there are exceptions where it makes sense to use pointers. It's good to know the exceptions.
The most compelling reason I have found is that it is expensive to have a list as a member variable when the list is expected to be empty most of the time. There are memory and time costs of constructing a list that can be avoided for most objects.
Here's a simplified example of something that is often found in CAD/CAE applications.
class Attribute;
class Entity
{
std::list<Attribute*>* attributes;
};
class Attribute: public Entity
{
};
Most Entity
s will not have Attribute
s but many will. These are use specified data as far as Entity
is concerned. A Part
, which is likely to be derived from Entity
, may have visual properties such as Color
, material properties such as Density
. However, a Face
of the Part
may have its own Color
. In the absence of its own Color
, a Face
inherits its containing Part
's Color
.
The key reason for using a std::list<Attribute*>*
instead of std::list<Attribute*>
is that it can be expensive to have a list for each object when most objects don't need it. The pointer will be assigned to NULL
in the constructor. When an object needs to have an item in the list, a list will be allocated from the heap and used henceforth.
The additional logic comes with the additional maintenance burden but the cost can be justified for the gains.
Update
For various reasons, we are still required to work with Microsoft Visual Studio 2008 on Windows 7 (64 bit). On that platform,
sizeof(std::list<Attribute*>)
is 48
sizeof(std::vector<Attribute*>)
is 40
sizeof(std::vector<Attribute*>*)
is 8.
With g++ 4.7.3 (32-bit), the sizes are:
sizeof(std::list<Attribute*>)
is 8
sizeof(std::vector<Attribute*>)
is 12
sizeof(std::vector<Attribute*>*)
is 4.
Depending on your platform, the additional cost of objects vs pointers can be prohibitive. A judgement call has to be made based on the numbers on a platform.