The general rule is to make the code as simple as possible.
So, for example, if you have a string as class member, like the student's name, you would definitely use std::string
, and not a smart pointer to it:
class Student {
...
std::string m_name; // *not* std::shared_ptr<std::string> m_name !!
};
On the other hand, if you need to represent shared ownership, like in your teacher-student example, using a std::shared_ptr
would be a better choice:
class Student {
...
std::shared_ptr<Teacher> m_teacher;
};
In this case, a single Teacher
instance is shared among different Student
s.
Moreover, if you can guarantee that the lifetime of the Teacher
instance is appropriate, i.e. it's longer than that of its Student
s, you can even simply use a raw observing pointer:
class Student {
...
// Raw observing pointer to Teacher.
// Note: Pay attention to the Teacher instance lifetime.
Teacher* m_teacher;
};