Copy constructors must take their argument by reference.
Operator overloads must take their arguments by value or reference, not by pointer.
For normal functions, the choice is yours; although you must use a pointer if you want to accept null arguments or dynamic arrays.
Some people prefer to use references whenever possible; there is no need to check whether it's null, and no scope for confusion about whether it refers to a single object or an array, or whether the function might delete the object. Others prefer to use pointers, as it gives a visible indication at the call site that the function might change the object.