С++ - Разница между (*). и ->?

Есть ли разница в производительности - или иначе - между:

ptr->a();

и

(*ptr).a(); 

?

Ответы

Ответ 1

Так как вы просите об этом в комментариях. То, что вы, вероятно, ищете, можно найти в стандарте (доступ к членству в 5.2.5 класса):

3 Если E1 имеет тип "указатель на класс" X ", то выражение E1- > E2 является преобразуется в эквивалентную форму (* (E1)) E2;.

Компилятор выдаст точные инструкции, и он будет таким же эффективным. Ваша машина не будет знать, написали ли вы "- > " или "*.".

Ответ 2

[изменить]

Если переменная определена как T * (где T - некоторый тип), то оба → и * являются одинаковыми (если только ptr не является нулевым).

Если переменная является экземпляром класса (по значению или по ссылке), то → и * должны вести себя одинаково (за лучшую практику), но это требует, чтобы класс перегружал их одинаково.

Ответ 3

Оператор -> является особенным в том, что в большинстве случаев он "сверлит-вниз" рекурсивно, пока результат выражения больше не является чем-то, для которого определен оператор перегрузки → . Выражение (*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 **, поэтому он не подходит.