Po pierwsze przy dynamicznej alokacji - to oczywiste. Chociaż od c++11 masz do tego specjalne sharde_ptr i unique_ptr
Po drugie - polimorfizm, ale to pewnie wiesz
class Base {}; class A : Base {}; class B : Base {}; A a; B b; Base *ptr = &a; ptr = &b;
Kolejna świetna możliwość jaką oferuje wskaźnik, to że może wskazywać na dowolny obiekt danego typu w pamięci. Więc załóżmy, że jakaś klasa chce tylko korzystać z jakiegoś obiektu (ale nie posiadać go) i daje nam do dyspozycji metode, za pomocą której przekażemy obiekt którego adres zostanie pobrany do wskaźnika i nasza klasa będzie od teraz korzystać z tego konkretnego obiektu.
Załóżmy, że mamy jakąś tam klase Game ze wskaźnikiem Renderer* od którgo zależy w jaki sposób nasza gra jest renderowana.
class Game { public: Renderer *m_ptrRenderer; void setRenderer(Renderer& _r) { m_ptrRenderer = &_r; } void update() { m_ptrRenderer->render(); } };
Za pomocą setRenderer możemy sobie ustawić dowolny obiekt Renderer kiedy tylko nam się podoba, a Game odrazu zacznie z niego korzystać. Musimy mieć tylko pewność, że obiekt cały czas w pamięci będzie, ale nie obchodzi nas gdzie on jest. To jest potęga wskaźników.
poleca inkrementację wskaźnika wskazującego na dany element tablicy.
Ostatecznie wychodzi na to samo. Kompletnie bez sensu się o to kłócić. Wygodniej jest korzystać z operatora [], więc tak robie. operator [] zwraca
*(przeakazy_wskaznik + przekazana_wartosc), więc nie ma znaczenia czy napiszesz tab[1] czy *(tab + 1). Z tym, że to pierwsze jest wygodniejsze.