When to use a member pointer variable in C ++

advertisements

I have a question about C++ design/implementation for best practice. I find myself having trouble deciding whether a member variable should be a pointer or not a pointer.

Lets say I have a class like this:

class Person{
     public:
        string name;
        int age;
        Child c;
};

Lets say that I want the "Child c" to be dynamic. Lets say that upon the creation of a "Person", I am not sure whether or not the Person has a child. It may be that the Person does have a child and does not have a child. And with this in mind, I want to be able to check in the code if the Person has a child.

Is it better to declare it as "Child* c" or "Child c"?

Given this, is it better to

class Person{
         public:
            string name;
            int age;
            Child* c;
    };


Introduction

If you want Person to either have a child, or not, there's really no question; you cannot declare Person to have a data-member of type Child. By having a child as data-member, Person will inconditionally have one as a member.

You can of course solve this by having a pointer-to-Child, then the Person will either be able to refer to a Child if such is present, or have a nullptr in the pointer-to-Child to express that no such child exists.


Further thoughts

You need to decide whether Person should own a child, or just be able to refer to one.

  • If you decide that Person is the owner of its child, you are recommended to express this ownership through a std::unique_ptr, this will also ease handling the lifetime of said child.

  • If you want Person to share a child between other instances (or other some other piece of code), use a std::shared_ptr.

  • If you just want Person to be able to refer to a child (no ownership at all), and being able to change what child (if any child at all) a Person refers to; use a raw-pointer.

  • If you want Person to be able to refer to a child already in existance, from the start- until the end of its lifetime, use a reference initalized by the constructor of Person.


What if I really want a child as data-member of every Person?

You could have Child contain some sort of information that would tell you about its inner state, having either "alive" or "is not alive" but this is not as clear in terms of expressiveness, or express the "has a child" inside Person using a similar method.