A 0 value can be provided to mean nothing. This can be used to provide optional arguments.
Pass by reference
Caller just passes the object -> transparent. Has to be used for operator overloading, since overloading for pointer types is not possible (pointers are builtin types). So you can’t do string s = &str1 + &str2; using pointers.
No 0 values possible -> Called function doesn’t have to check for them
Reference to const also accepts temporaries: void f(const T& t); ... f(T(a, b, c));, pointers cannot be used like that since you cannot take the address of a temporary.
Last but not least, references are easier to use -> less chance for bugs.