A reference is another name for an existing object; a pointer is an object that stores an address.
That difference drives everything else. A reference must be initialized when declared and can never be reseated to a different object. A pointer can be null, can be reassigned, and can be moved through an array with arithmetic. A pointer also has its own storage and its own address; a reference usually has neither.
Practically: use a reference when the thing must exist and will not change identity. Use a pointer when absence is meaningful, when you need to rebind, or when you walk memory.
References make the contract clearer at the call site. A function taking const std::string& promises it will not be handed nothing, so it needs no null check.
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.
Why there's no diagram: “”
The interactive diagram is below the answer - jump to diagram ↓ · Below it, the related concept . Jump to it ↓
The diagram below the answer is the concept . Jump to it ↓