If you want to use them as function parameters, pass them by reference, not by value.
void function1(Person p)
{
// p is a copy
}
void function2(Person& p)
{
// p is a reference to the object passed
// in as a parameter, not a copy
}
If you use shared_ptr, remember that you have to make every Person who will be a parent a shared_ptr, otherwise its child will try to delete it (which it has no right to do) when the last goes out of scope. If you want to create a clone of a Person, and clone its relations, you will need to think hard about lifetime management and ownership. What should happen if you tried to clone father? Should it create a clone of grandfather? That is quite simple to do, but it means father will have to delete its grandfather clone in its destructor. Then what happens if another Person has that grandfather as a parent?