Подтвердить что ты не робот

Какова цель указателя "this" в С++?

Какова цель ключевого слова this. Разве методы в классе не имеют доступа к другим членам-сверстникам в одном классе? В чем необходимость вызова метода this для вызова одноранговых методов внутри класса?

4b9b3361

Ответ 1

Два основных использования:

  • Чтобы передать *this или this в качестве параметра другим, неклассическим методам.

    void do_something_to_a_foo(Foo *foo_instance);
    
    void Foo::DoSomething()
    {
        do_something_to_a_foo(this);
    }
    
  • Позволяет устранить неоднозначность между переменными-членами и параметрами функции. Это характерно для конструкторов.
    MessageBox::MessageBox(const string& message)
    {
      this->message = message;
    }
    (Хотя список инициализации обычно предпочтительнее назначения в этом конкретном примере.)

Ответ 2

  • Помогает в устранении неоднозначных переменных.
  • Передайте себя как параметр или верните себе результат

Пример:

struct A
{
    void test(int x)
    {
        this->x = x;                 // Disambiguate. Show shadowed variable.
    }
    A& operator=(A const& copy)
    {
        x = copy.x;
        return *this;                // return a reference to self
    }

    bool operator==(A const& rhs) const
    {
         return isEqual(*this, rhs); // Pass yourself as parameter.
                                     // Bad example but you can see what I mean.
    }

    private:
        int x;
};

Ответ 3

Рассмотрим случай, когда параметр имеет то же имя, что и член класса:

void setData(int data){
  this->data = data;
}

Ответ 4

Выражение *this обычно используется для возврата текущего объекта из функции-члена:

return *this;

Указатель this также используется для защиты от саморекламы:

if (&Object != this) {
// do not execute in cases of self-reference

Ответ 5

  • Устранение двусмысленности между переменными-членами/функциями и функциями, определенными в других областях
  • Сделать явным для читателя код, вызываемый функцией-членом или ссылкой на переменную-член.
  • Триггер IntelliSense в среде IDE (хотя это может быть только я).

Ответ 6

Он позволяет передать текущий объект другой функции:

class Foo;

void FooHandler(Foo *foo);

class Foo
{
    HandleThis()
    {
       FooHandler(this);
    }  
};

Ответ 7

Некоторые моменты, которые следует иметь в виду

  • Этот указатель сохраняет адрес экземпляр класса, чтобы включить указатель доступ членов к члену функции класса.

  • Этот указатель не учитывается для вычисляя размер объекта.

  • Эти указатели недоступны для статические функции-члены.

  • Эти указатели не изменяются

Посмотрите следующий пример, чтобы понять, как использовать указатель 'this', описанный в этом учебнике по С++.

class this_pointer_example // class for explaining C++ tutorial 
{
    int data1;
 public:
    //Function using this pointer for C++ Tutorial
    int getdata()
    { 
        return this->data1;
    } 
  //Function without using this pointer 
  void setdata(int newval)
  {
       data1 = newval;
  }
};

Таким образом, функция-член может получить доступ к элементу данных либо с помощью этого указателя, либо без него. Также прочитайте this, чтобы понять некоторые другие основные вещи об этом указателе

Ответ 8

Это позволяет вам обходить членов, затененных аргументами метода или локальными переменными.

Ответ 9

Указатель this внутри класса является ссылкой на себя. Это необходимо, например, в этом случае:

class YourClass
{
   private:
      int number;

   public:
      YourClass(int number)
      {
         this->number = number;
      }
}

(хотя это было бы лучше сделано с помощью списка инициализации, это служит для демонстрации)

В этом случае у вас есть две переменные с тем же именем

  • Класс private "number"
  • И параметр конструктора "number"

Используя this->number, вы даете компилятору знать, что вы назначаете переменную класса-привата.

Ответ 10

Например, если вы пишете operator=(), вы должны проверить самоназначение.

class C {
public:
    const C& operator=(const C& rhs)
    {
        if(this==&rhs) // <-- check for self assignment before anything
            return *this;
        // algorithm of assignment here
        return *this; // <- return a reference to yourself
    }
};

Ответ 11

Указатель this - это способ доступа к текущему экземпляру конкретного объекта. Его можно использовать для нескольких целей:

  • как представление идентичности экземпляра (например, по сравнению с другими экземплярами)
  • для сопоставления данных и локальных переменных.
  • передать текущий экземпляр внешним объектам
  • чтобы передать текущий экземпляр другому типу

Ответ 12

Иногда вы хотите напрямую ссылаться на текущий объект, чтобы передать его другим методам или сохранить его для последующего использования.

Кроме того, вызовы методов всегда происходят против объекта. Когда вы вызываете метод внутри другого метода в текущем объекте, это эквивалентно записи this- > methodName()

Вы также можете использовать это для доступа к члену, а не к имени переменной или аргумента, которое "скрывает" его, но это (IMHO) неверная практика, чтобы скрыть имя. Например:

void C:: setX (int x) {   this- > x = x; }

Ответ 13

Для ясности или для устранения двусмысленности, когда локальная переменная или параметр имеет то же имя, что и переменная-член.

Ответ 14

Он также позволяет тестировать самоопределение при перегрузках оператора присваивания:

Object & operator=(const Object & rhs) {
  if (&rhs != this) {
    // do assignment
  }
  return *this;
}

Ответ 15

Он также позволяет объектам удалять себя. Это используется для реализации интеллектуальных указателей, программирования COM и (я думаю) XPCOM.

Код выглядит так (выдержка из какого-то более крупного кода):

class counted_ptr
{
private:
    counted_ptr(const counted_ptr&);
    void operator =(const counted_ptr&);

    raw_ptr_type            _ptr;
    volatile unsigned int   _refcount;
    delete_function         _deleter;
public:

    counted_ptr(raw_ptr_type const ptr, delete_function deleter)
        : _ptr(ptr), _refcount(1), _deleter(deleter) {}
    ~counted_ptr() { (*_deleter)(_ptr); }
    unsigned int addref() { return ++_refcount; }
    unsigned int release()
    {
        unsigned int retval = --_refcount;
        if(0 == retval)
>>>>>>>>        delete this;
        return retval;
    }
    raw_ptr_type get() { return _ptr; }
};

Ответ 16

Двойной двоеточие в С++ технически известен как "оператор разрешения Unary Scope". В основном это используется, когда мы повторяем одну и ту же переменную, например, внутри нашей "основной" функции (где наша переменная будет называться локальной переменной) и внешней основной (где переменная называется глобальной переменной). С++ будет вызывать внутреннюю переменную (то есть локальную). Итак, представьте, что вы хотите использовать глобальную переменную "Conundrum" вместо локальной, потому что глобальная выражается как float, а не как целое число:

#include <iostream>
using namespace std;

float Conundrum=.75;

int main()
{
  int Conundrum =75;
  cout<<::Conundrum;

}

Итак, в этом случае программа будет использовать наш плавающий Conundrum вместо int Conundrum.

Ответ 17

Еще одна цель - связать объект: Рассмотрим следующий класс:

class Calc{
private:
    int m_value;

public:
    Calc() { m_value = 0; }

    void add(int value) { m_value += value; }
    void sub(int value) { m_value -= value; }
    void mult(int value) { m_value *= value; }

    int getValue() { return m_value; }
};

Если вы хотите добавить 5, вычесть 3 и умножить на 4, вам нужно сделать следующее:   #включают   int main()   {       Calc calc;       calc.add(5);//возвращает void       calc.sub(3);//возвращает void       calc.mult(4);//возвращает void

    std::cout << calc.getValue() << '\n';
    return 0;
}

Однако, если мы сделаем каждую функцию return * this, мы можем связать вызовы вместе. Вот новая версия Calc с "цепными" функциями:

class Calc
{
private:
    int m_value;

public:
    Calc() { m_value = 0; }

    Calc& add(int value) { m_value += value; return *this; }
    Calc& sub(int value) { m_value -= value; return *this; }
    Calc& mult(int value) { m_value *= value; return *this; }

    int getValue() { return m_value; }
};

Обратите внимание, что add(), sub() и mult() теперь возвращают * это. Следовательно, это позволяет нам сделать следующее:

#include <iostream>
int main()
{
    Calc calc;
    calc.add(5).sub(3).mult(4);

    std::cout << calc.getValue() << '\n';
    return 0;
}

Мы эффективно сконденсировали три строки в одно выражение.

Скопировано из: http://www.learncpp.com/cpp-tutorial/8-8-the-hidden-this-pointer/