Как и когда правильно использовать * этот указатель и сопоставление аргументов? - PullRequest
4 голосов
/ 29 сентября 2010

Когда я просматриваю код, написанный коллегами, в определенном месте они используют:

this->doSomething(); //-->case A
doSomething(); //-->case B

На самом деле я не уверен насчет использования * этого указателя ...: (

Другой вопрос с сопоставлением аргументов:

obj.doOperation();  //-->case C
(&obj)->doOperation(); //-->case D

Фактически оба случая выполняют желаемую операцию, это просто способ заставить код выглядеть более сложным?

ЧтоВаша рекомендация по двум вышеуказанным вопросам: когда подходящее время их использовать и почему?

Ответы [ 3 ]

5 голосов
/ 29 сентября 2010

Это не ответ на ваш вопрос, а примечание, что оба фрагмента могут делать разные вещи:

namespace B { void doSomething() {} }

struct A {    
    void f()
    {
        using B::doSomething;
        this->doSomething(); // call A::doSomething
        doSomething(); // calls B::doSomething
    }

    int a;
    void g(int a)
    {
        this->a = a; // assigns argument to member
    }

    A* operator & () { return this; }
    void doOperation() {}
    void doSomething() {}
};

void g(A &obj)
{
    obj.doOperation();  // calls A::doOperation directly
    (&obj)->doOperation(); // calls A::operator & first
}
3 голосов
/ 29 сентября 2010

Случаи В и С всегда являются подходящим способом. Случаи A и D эквивалентны и не делают ничего другого.

Несколько исключений из этого:

  • Если у класса есть перегруженный operator&, который делает удивительные вещи, то случай D может сделать что-то отличное от C. На самом деле наличие классов, которые делают это, не рекомендуется, так как это может сбить с толку.
  • Если есть локальная переменная doSomething (или что-то еще с таким именем в локальной области видимости), то A будет ссылаться на doSomething, отличное от B. Опять не рекомендуется вмешиваться в такое ситуации, лучше дать разные имена разным вещам.
1 голос
/ 29 сентября 2010

C и D разные.Если doOperation является виртуальным, случай D будет выполнять виртуальный вызов, случай C будет выполнять не виртуальный вызов, если obj не является ссылкой.Это предполагает, однако, что operator& и operator-> не были перегружены.

Я склонен использовать A над B, так как может быть локальный doSomething идентификатор.Внутри кода шаблона все может ухудшиться (хотя сейчас я не могу привести точный пример).Это хорошая привычка.

...