Это немного безопаснее, но не одно и то же. Обратите внимание, что у вас есть те же проблемы с «висячими ссылками», что и с «висящими указателями». Например, возврат ссылки из объекта с областью видимости приводит к неопределенному поведению, точно так же, как указатели:
int& f() { int x = 2; return x; }
Единственное преимущество в том, что вы не можете создать нулевую ссылку. Даже если ты стараешься:
int& null_ref = *((int*)0); // Dereferencing a null pointer is undefined in C++
// The variable null_ref has an undefined state.
Как члены класса, указатели предпочтительнее, так как они имеют лучшую семантику присваивания: вы не можете переназначить ссылку, когда она инициализирована. Компилятор не сможет предоставить оператор присваивания по умолчанию, если в классе есть ссылочные члены.
Следовательно, C ++ не может избавиться от указателей, и вы можете использовать их свободно: передавая аргументы как указатели, а не как (не константные) ссылки, вы даете понять на сайте вызова, что объект будет изменен. Это может добавить немного безопасности, так как вы видите невооруженным глазом, какие функции на самом деле изменяют объекты.
Я немного играю адвоката дьявола, но ссылками легко злоупотреблять.