operator->
может быть перегружено только как функция-член класса, но не для обычного указателя.
Как правило, нет способа проверить, что (ненулевой) указатель действительно указывает на допустимый объект. В вашем примере delete pObj;
ничего не делает для изменения указателя; он просто указывает на недействительную память, и нет способа проверить это. Таким образом, даже если бы вы могли перегрузить operator->
здесь, лучшее, что он мог сделать, это проверить, что оно не равно нулю.
Обычный подход заключается в использовании умных указателей, а не обычных указателей. Интеллектуальный указатель - это класс, который оборачивает простой указатель на объект и имеет перегрузки operator*
и operator->
, так что он выглядит и ощущается как указатель. Вы не будете удалять объект напрямую, но через указатель (когда он выходит из области видимости или явно, вызывая функцию reset()
), и указатель может затем установить его простой указатель на ноль, когда это произойдет. Таким образом, простой указатель всегда будет либо действительным, либо нулевым, поэтому перегруженные операторы могут полезно проверить его перед разыменованием.
Умные указатели (и RAII в целом) также предоставляют другие преимущества: автоматическое управление памятью и безопасность исключений. В вашем коде произойдет утечка памяти, если DoStuff()
сгенерирует исключение; pObj
выйдет из области видимости, и поэтому не будет никакого доступа к нему, чтобы удалить объект, на который он указывает. Память будет потеряна, и, если это будет продолжаться, вы в конечном итоге будете использовать всю системную память и либо зависать, либо медленно сканировать. Если бы это был умный указатель, то объект был бы удален автоматически, поскольку он вышел из области видимости.
Обычно используются интеллектуальные указатели из стандартной библиотеки и Boost auto_ptr
, scoped_ptr
и shared_ptr
, каждый из которых отличается при копировании указателя. C ++ 0x представит unique_ptr
вместо auto_ptr
.