This operator in cpp

this указатель _

Выражение this является выражением rvalue ( до C++11) и значением prvalue (начиная с C++11) , значением которого является адрес неявного параметра объекта (объект, для которого вызывается нестатическая функция-член). Он может появляться в следующих контекстах:

2) в объявлении нестатической функции-члена в любом месте после (необязательной) последовательности cv-qualifier, включая

Explanation

this может быть связано только с самым внутренним охватывающим классом его внешнего вида, даже если внешний вид недействителен в контексте:

class Outer < int a[sizeof(*this)]; // ошибка: не внутри функции-члена unsigned int sz = sizeof(*this); // ОК: в инициализаторе члена по умолчанию void f() < int b[sizeof(*this)]; // OK struct Inner < int c[sizeof(*this)]; // ошибка: не внутри функции-члена Inner // 'это' не связано с внешним // даже если он находится внутри функции-члена Outer >; > >;

Тип this в функции-члене класса X — X* (указатель на X). Если функция-член объявлена ​​с последовательностью cv-qualifier cv , типом this является cv X* (указатель на идентично cv-квалифицированный X). Поскольку конструкторы и деструкторы не могут быть объявлены с cv-квалификаторами, тип this в них всегда X* , даже при создании или уничтожении константного объекта.

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

В шаблонах классов this является зависимым выражением , и явное this-> может использоваться, чтобы заставить другое выражение стать зависимым.

templatetypename T> struct B < int var; >; templatetypename T> struct D : B < D() < // переменная = 1; // ошибка: 'var' не был объявлен в этой области видимости this->var = 1; // OK > >;

Во время конструирования объекта, если к значению объекта или любому из его подобъектов получают доступ через glvalue, который не получен, прямо или косвенно, из указателя конструктора this , значение полученного таким образом объекта или подобъекта не определено. Другими словами, указатель this не может быть псевдонимом в конструкторе:

extern struct D d; struct D < D(int a) : a(a), b(d.a) <> // b (a) или b (this-> a) будет правильным int a, b; >; D d = D(1); // поскольку b (da) не получил a через это, db теперь не определен

Можно выполнить delete this; , если программа может гарантировать, что объект был выделен с помощью new , это делает недействительным каждый указатель на освобожденный объект, включая сам указатель this : после delete this; возвращает, такая функция-член не может ссылаться на член класса (поскольку это включает неявное разыменование this ) и никакая другая функция-член не может быть вызвана.

Это используется, например, в функции-члене управляющего блока std::shared_ptr , отвечающей за уменьшение счетчика ссылок, когда последняя ссылка на управляемый объект выходит за пределы области видимости.

class ref < // . void incRef( ) < ++mnRef; >void decRef( ) < if (--mnRef == 0) delete this; > >;

Keywords

Example

class T < int x; void foo() < x = 6; // то же самое -> x = 6; this->x = 5; // явное использование this-> > void foo() const < // x = 7; // Ошибка: * это константа > void foo(int x) // параметр x затеняет член с тем же именем < this->x = x; // неквалифицированный x относится к параметру // 'this->' требуется для устранения неоднозначности > int y; T(int x) : x(x), // использует параметр x для инициализации члена x y(this->x) // использует член x для инициализации члена y <> T& operator=(const T& b) < x = b.x; return *this; // многие перегруженные операторы возвращают * this > >;

Defect reports

Следующие отчеты о дефектах,изменяющих поведение,были применены ретроактивно к ранее опубликованным стандартам C++.

Читайте также:  Python ctime to datetime
DR Applied to Поведение в опубликованном виде Correct behavior
CWG 760 C++98 когда this используется во вложенном классе, это было
не определено,связано ли это с
вложенный класс или объемлющий класс
this всегда связано с
самый внутренний вложенный класс,
независимо от того,находится ли он в
нестатическая функция-член
CWG 2271 C++98 this может быть псевдонимом при создании неконстантного объекта псевдоним также
запрещено в данном случае
C++

Шаблон-это объект C++,определяющий одно из следующих действий:Шаблоны параметризуются одним или несколькими параметрами,трех видов:тип-нетип и Когда

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

Источник

This operator in cpp

Ключевое слово this представляет указатель на текущий объект данного класса. Соответственно через this мы можем обращаться внутри класса к любым его членам.

#include class Point < public: Point(int x, int y) < this->x = x; this->y = y; > void showCoords() < std::cout x private: int x; int y; >; int main() < Point p1; p1.showCoords(); >

В данном случае определен класс Point, который представляет точку на плоскости. И для хранения координат точки в классе определены переменные x и y.

Для обращения к переменным используется указатель this . Причем после this ставится не точка, а стрелка -> .

В большинстве случаев для обращения к членам класса вряд ли поднадобится ключевое слово this. Но оно может быть необходимо, если параметры функции или переменные, которые определяются внутри функции, называются также как и переменные класса. К примеру, чтобы в конструкторе разграничить параметры и переменные класса как раз и используется указатель this.

Другое практическое применение this — с его помощью можно возвращать текущий объект класса:

#include class Point < public: Point(int x, int y) < this->x = x; this->y = y; > void showCoords() < std::cout Point &move(int x, int y) < this->x += x; this->y += y; return *this; > private: int x; int y; >; int main() < Point p1; p1.showCoords(); // Point x: 20 y: 50 p1.move(10, 5).move(10, 10); p1.showCoords(); // Point x: 40 y: 65 >

Здесь метод move с помощью указателя this возвращает ссылку на объект текущего класса, осуществляя условное перемещение точки. Таким образом, мы можем по цепочке для одного и того же объекта вызывать метод move:

Читайте также:  Java строки найти символ

Здесь также важно отметить возвращение не просто объекта Point, а ссылки на этот объект. Так, в данном случае выге определенная строка фактически будет аналогично следующему коду:

Но если бы метод move возвращал бы не ссылку, а посто объект:

Point move(int x, int y) < this->x += x; this->y += y; return *this; >

То вызов p1.move(10, 5).move(10) был бы фактически эквивалентен следующему коду:

Point temp = p1.move(10, 5); temp.move(10, 10);

Где второй вызов метода move вызывался бы для временной копии и никак бы не затрагивал переменную p1.

В качестве альтернативы можно возвращать сам указатель this :

#include class Point < public: Point(int x, int y) < this->x = x; this->y = y; > void showCoords() < std::cout x Point* move(int x, int y) < this->x += x; this->y += y; return this; > private: int x; int y; >; int main() < Point p1; p1.showCoords(); // Point x: 20 y: 50 p1.move(10, 5)->move(10, 10)->move(10, 15); p1.showCoords(); // Point x: 50 y: 80 >

В данном случае, поскольку функция move() возвращает указатель this, то у результата функции мы также можем вызвать функцию move через операцию -> :

p1.move(10, 5)->move(10, 10)->move(10, 15)
#include class Integer < public: Integer(int number) < value=number; >Integer& add(const Integer& obj) < value += obj.value; return *this; >Integer& subtract(const Integer& obj) < value -= obj.value; return *this; >Integer& multiply(const Integer& obj) < value *= obj.value; return *this; >void print() const < std::cout private: int value; >; int main() < Integer num; num.add(Integer).subtract(Integer).multiply(Integer); num.print(); // Value: 50 >

Здесь класс Integer представляет условно целое число, которое хранится в переменной value. В нем определены функции add() (сложение), subtract() (вычитание), и multiply() (умножение), которые принимают другой объект Integer и выполняеют соответствующую операцию между текущим объектом и аргументом. Причем каждая из этих функций возвращает текущий объект, благодаря чему эти функции можно было выполнить по цепочке:

Integer num; num.add(Integer).subtract(Integer).multiply(Integer);

Источник

Указатель this

Указатель this является указателем, доступным только в нестатических функциях-членах class типа , struct или union . Он указывает на объект, для которого вызывается функция-член. Статические функции-члены не имеют указателя this .

Синтаксис

this this->member-identifier 

Remarks

Указатель объекта this не является частью самого объекта. Он не отражается в результате sizeof оператора для объекта . При вызове нестатической функции-члена для объекта компилятор передает адрес объекта функции в качестве скрытого аргумента. Например, при вызове следующей функции

может интерпретироваться следующим образом:

Адрес объекта доступен из функции-члена в качестве указателя this . Большинство this вариантов использования указателей являются неявными. Использовать явное this выражение при ссылке на члены элемента является законным, хотя и ненужным class. Пример:

void Date::setMonth( int mn ) < month = mn; // These three statements this->month = mn; // are equivalent (*this).month = mn; > 

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

Читайте также:  Write into txt file python

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

this Так как указатель неизменяем, назначения указателю this не допускаются. Более ранние реализации C++ позволяли присваивать . this

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

Пример

// this_pointer.cpp // compile with: /EHsc #include #include using namespace std; class Buf < public: Buf( char* szBuffer, size_t sizeOfBuffer ); Buf& operator=( const Buf & ); void Display() < cout private: char* buffer; size_t sizeOfBuffer; >; Buf::Buf( char* szBuffer, size_t sizeOfBuffer ) < sizeOfBuffer++; // account for a NULL terminator buffer = new char[ sizeOfBuffer ]; if (buffer) < strcpy_s( buffer, sizeOfBuffer, szBuffer ); sizeOfBuffer = sizeOfBuffer; >> Buf& Buf::operator=( const Buf &otherbuf ) < if( &otherbuf != this ) < if (buffer) delete [] buffer; sizeOfBuffer = strlen( otherbuf.buffer ) + 1; buffer = new char[sizeOfBuffer]; strcpy_s( buffer, sizeOfBuffer, otherbuf.buffer ); >return *this; > int main() < Buf myBuf( "my buffer", 10 ); Buf yourBuf( "your buffer", 12 ); // Display 'my buffer' myBuf.Display(); // assignment operator myBuf = yourBuf; // Display 'your buffer' myBuf.Display(); >

Тип указателя this

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

// type_of_this_pointer1.cpp class Point < unsigned X() const; >; int main()

В приведенном выше коде объявляется функция-член , X в которой this указатель обрабатывается как const указатель на const объект . Можно использовать сочетания параметров cv-mod-list , но они всегда изменяют объект, на который this указывает указатель, а не сам указатель. В следующем объявлении объявляется функция X , где this указатель является указателем const на const объект :

// type_of_this_pointer2.cpp class Point < unsigned X() const; >; int main()

Тип this в функции-члене описывается следующим синтаксисом. Определяется cv-qualifier-list из декларатора функции-члена. Это может быть const или volatile (или и то, и другое). class-type — это имя class:

[ cv-qualifier-list ] class-type * const this

Другими словами this , указатель всегда является указателем const . Его нельзя переназначить. Квалификаторы const или volatile , используемые в объявлении функции-члена, применяются к экземпляру class this , на который указывает указатель, в область этой функции.

В следующей таблице приведены дополнительные сведения о том, как работают эти модификаторы.

Семантика модификаторов this

Модификатор Значение
const Не удается изменить данные члена; не может вызывать функции-члены, которые не const являются .
volatile Данные-члены загружаются из памяти при каждом обращении к ним; отключает определенные оптимизации.

Ошибка при передаче const объекта в функцию-член, которая не const является .

Аналогичным образом также возникает ошибка при передаче volatile объекта в функцию-член, которая не volatile является .

Функции-члены, this объявленные как const , не могут изменять данные членов — в таких функциях указатель является указателем на const объект .

Constructors и destructors нельзя объявить как const или volatile . Однако они могут вызываться для const объектов или volatile .

Источник

Оцените статью