Потому что иногда вещи не должны быть переориентированы. (Например, ссылка на синглтон.)
Потому что в функции замечательно знать, что ваш аргумент не может быть нулевым.
Но в основном потому, что он позволяет использовать что-то, что действительно является указателем, но действует как объект локального значения. C ++ старается изо всех сил, цитируя Страуструпа, заставлять экземпляры классов «делать как целые числа d». Передача int через vaue - это дешево, потому что int вписывается в машинный регистр. Классы часто больше чем целые, и передача их по значению имеет значительные накладные расходы.
Возможность передавать указатель (который часто имеет размер типа int или, может быть, два целых), который «похож на» объект-значение, позволяет нам писать более чистый код без «подробностей реализации» разыменований. И, наряду с перегрузкой операторов, это позволяет нам писать классы, использующие синтаксис, подобный синтаксису, используемому с int. В частности, он позволяет нам писать классы шаблонов с синтаксисом, который может быть одинаково применен к примитивам, таким как целые и классы (например, класс комплексных чисел).
И, особенно с перегрузкой операторов, есть места, где мы должны возвращать объект, но опять же, намного дешевле вернуть указатель. Oncve снова, возвращая ссылку, наш "вне".
И указатели сложны. Может быть, не для вас, и не для тех, кто понимает указатель - это просто значение адреса памяти. Но, вспомнив мой класс CS 101, они запутали нескольких учеников.
char* p = s; *p = *s; *p++ = *s++; i = ++*p;
может сбить с толку.
Черт возьми, после 40 лет C люди до сих пор не могут даже согласиться, если объявление указателя должно быть:
char* p;
или
char *p;