-> の形式は、ポインターの参照を解除してメンバーにアクセスするための省略形です。
(*ptr).field;
// Equiv to
ptr->field;
-> を使用する正当な理由の 1 つは、チェーンをたどっている場合です。
int x = (*(*(*(*ptr).field1).field2).field3).field4;
// Equiv to
int y = ptr->field1->field2->field3->field4;
2番目のものははるかに読みやすくなります。
あなたの質問の2番目の部分について。
例を思いつくのは本当に簡単だと思います。
#include <iostream>
class Shape
{
public: virtual ~Shape() {}
virtual void Print() {std::cout << "Shape\n";}
};
class Point: public Shape
{
public: virtual void Print() {std::cout << "Point\n";}
};
int main ()
{
Point p;
Shape* s = &p;
s->Print();
(*s).Print();
}
> vi x.cpp
> g++ x.cpp
> ./a.exe
Point
Point
ご覧のとおり、どちらの状況でも結果は同じです。
ポインターまたは参照を介してメソッドを呼び出すと、仮想呼び出しメカニズムが呼び出されます。スター オペレーター (別名 derefence オペレーター) は、オブジェクトへの参照を返します (実際にオブジェクトを逆参照するわけではありません)。したがって、メソッドを呼び出すために使用されると、仮想呼び出しメカニズムが呼び出され、メソッドの最も派生したバージョンが呼び出されます。