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

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

ptr->a();

и

(*ptr).a(); 

?

3 ответов


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

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

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


[Edit]

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

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


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

обратите внимание, однако, что это не будет compile:

cout << objCHandle->x << endl;

потому что детализация поведения -> происходит только тогда, когда левая сторона выражения является классом, структурой, объединением или общим типом. В этом случае objCHandle является MyClass**, поэтому он не подходит.