C ++ - Разница между (*). и ->? - PullRequest
13 голосов
/ 18 марта 2010

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

ptr->a();

и

(*ptr).a(); 

Ответы [ 3 ]

15 голосов
/ 18 марта 2010

[Изменить]

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

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

12 голосов
/ 18 марта 2010

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

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

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

7 голосов
/ 18 марта 2010

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

...