Оператор ->
является особенным в том, что в большинстве случаев он рекурсивно «сверлит», пока результат выражения больше не будет чем-то, для чего определен перегруженный оператор ->. Выражение (*subxpression).x
выполняет только одно разыменование подвыражения, поэтому, если результатом (*subexpression)
является другой указатель, он не скомпилируется (вам нужно написать (*(*subexpression)).x
. Для лучшей иллюстрации смотрите следующий код:
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass() : x(0) {}
int x;
};
class MyPtr
{
private:
MyClass* mObj;
public:
MyPtr(MyClass* obj) : mObj(obj) {}
MyClass* operator->()
{
return mObj;
}
};
int main()
{
MyClass obj;
MyClass* objCPtr = &obj;
MyClass** objCHandle = &objCPtr;
MyPtr ptr(&obj);
cout << ptr->x << endl;
cout << (*(*objCHandle)).x << endl;
}
Обратите внимание, что это не скомпилируется:
cout << objCHandle->x << endl;
Поскольку поведение детализации -> происходит только тогда, когда левая часть выражения является классом, структурой, объединением или универсальным типом. В этом случае objCHandle - это MyClass **, поэтому он не подходит.