Перейти к содержимому

This c что это

  • автор:

Указатель this C++

Вместо того, чтобы сразу давать определение, что же это такое — указатель this , предлагаю рассмотреть вместе с вами два простейших примера. В одном мы просто определим две функции setData() и getData() . Одна будет предлагать пользователю ввести данные, вторая будет выводить их на экран соответственно. И обратимся к ним из главной функции main() . А во втором примере, мы создадим класс class SetGetData , методы которого так же будут вносить данные и выводить их на экран. Забегая наперед, скажу, что основным отличием этих функций и методов станет то, как они принимают параметры (аргументы).

#include using namespace std; void setData(char *s, int &n) //функция для принятия данных < cout > n; > void getData(char s[], int n) //отображение данных < cout int main() < setlocale(LC_ALL, "rus"); char str[128] = ""; //объявляем и инициализируем переменные для очистки от мусора int number = 0; setData(str, number); //вызов функций system("cls"); //очистка экрана перед выводом данных на экран getData(str, number); return 0; >

Этот пример, скорей всего, не вызвал у вас никаких вопросов и трудностей в его понимании, если уж вы дошли до изучения этой темы. Тут мы определили две функции — строки 5 — 16. Функция setData(char *s, int &n) принимает два параметра: указатель на строку и адрес переменной типа int , для того чтобы внести изменения в переменные, которые ей передадутся при вызове. Функция getData(char s[], int n) отобразит строку и число , измененные пользователем. Далее в main- функции мы просто объявляем переменные и передаем их в наши функции при вызове.

Результатом работы будет, к примеру, такое сообщение:

CppStudio.com

cppstudio.com - site N1

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

Теперь рассмотрим второй пример (Тут вы уже сразу обратите внимание на то, что мы не передаем параметры в методы ни при определении, ни при вызове методов):

#include using namespace std; class SetGetData //определяем класс < char str[128]; int number; public: void setData() //метод класса, который принимает данные < cout > number; > void getData() //метод класса, который выводит данные на экран < cout >; int main() < setlocale(LC_ALL, "rus"); SetGetData object; //создаем объект класса object.setData(); //вносим данные system("cls"); //очистка экрана перед выводом данных на экран object.getData(); //данные отображаем на экране return 0; >

Вы видите, что явно мы ни при определении, ни при вызове методов через объект, не указываем с какими параметрами будут работать методы класса. Все дело в том, что при вызове методов, которые принадлежат классу, им неявно передается тот самый указатель this . Это происходит автоматически и незаметно для нас, так как он является скрытым первым параметром любого метода-элемента класса. Указатель this указывает на адрес созданного объекта класса — в нашем случае он получает адрес объекта object и указывает методу setData() в какие элементы объекта надо внести измененные данные, а методу getData() — элементы какого объекта надо отобразить на экране.

Важно знать, что у нас есть возможность использовать указатель this явно. Так, к примеру, выглядело бы определение метода getData() , если бы мы использовали this явно:

void getData() //метод класса, который выводит данные на экран < cout str number

Такая запись так же «пройдет»:

void getData() < cout 

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

Теперь можно и определение дать! Указатель this — это указатель на адрес объекта класса, при этом он является скрытым первым параметром любого метода класса (кроме статических методов), а типом указателя выступает имя класса. И еще кое-что из теории:

  • this является зарезервированным словом С++;
  • мы можем использовать this явно в методах-элементах класса;
  • а вот явно объявить, инициализировать либо изменить указатель this , возможности нет;

Так, совсем коротко, мы дали вам основную информацию по этой теме. Остались вопросы? Задавайте их в комментариях к статье. Без ответа мы вас не оставим.

К сожалению, для данной темы пока нет подходящих задач. Если у вас есть таковые на примете, отправте их по адресу: admin@cppstudio.com. Мы их опубликуем!

Указатель this С++

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

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

Когда будете рассматривать эти примеры, обратите внимание на то, как функции из первого примера и методы класса из второго примера, будут принимать параметры.

Первый пример:
using namespace std ;
void enterData ( char * someName , int & someAge )
cout << "Ваше имя: " ; cin . getline ( someName , 128 ) ; cout << "Ваш возраст: " ; cin >> someAge ;
void showData ( char * someName , int & someAge )
cout << "\n" << someName << " " << someAge << endl << endl ; setlocale ( LC_ALL , "rus" ) ; char name [ 128 ] = "" ; int age = 0 ; enterData ( name , age ) ; showData ( name , age ) ;

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

using namespace std ;
class SetShowData
char someName [ 128 ] ;
int someAge ;
void enterData ( )
cout << "Ваше имя: " ; cin . getline ( someName , 128 ) ; cout << "Ваш возраст: " ; cin >> someAge ;
void showData ( )
cout << "\n" << someName << " " << someAge << endl << endl ; setlocale ( LC_ALL , "rus" ) ; SetShowData objectOfClass ; objectOfClass . enterData ( ) ; // вызов метода для ввода данных objectOfClass . showData ( ) ; //вызов метода для отображения данных

Рассмотрев этот пример, вы увидели, что определяя методы в теле класса, мы не прописываем параметры в сигнатуре. И вызывая эти методы из главной функции, мы так же не указываем с какими данными им работать. Но каким-то образом данные вносятся именно в те члены класса, которые указаны в теле методов.

Как же методы “понимают”, с какими данными и с каким объектом класса им надо работать? Дело в том, что в методы класса, неявно передается в виде параметра указатель this (указатель на объект класса). Происходит это автоматически. Мы этого не видим, так как этот указатель – есть скрытый первый параметр любого метода класса.

Указатель this хранит адрес определённого объекта класса. В рассмотренном примере он хранит адрес объекта objectOfClass . Таким образом он неявно указывает методам класса с данными какого объекта надо работать.

Отмечу, что у программистов все же есть возможность применять указатель this явно. Если бы мы определяли метод enterData() с явным использованием this , это выглядело бы так:

указатель this в c++, this c++, this с++

указатель this в c++, this c++, this с++

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

Ключевое слово this в C++

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

1-1801-30e499.png

В нашем примере определен класс Point, представляющий точку на плоскости. Для того чтобы хранить координаты этой точки, в классе определены переменные x и y.

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

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

Кроме того, используя this, вы сможете возвращать текущий объект класса:

2-1801-68c196.png

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

3-1801-5782c9.png

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

4-1801-fcff77.png

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

5-1801-584269.png

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

6-1801-d1b08e.png

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

this Указатель

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

Синтаксис

this this->member-identifier 

Замечания

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

myDate.setMonth( 3 ); 

можно интерпретировать как:

setMonth( &myDate, 3 ); 

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

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

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

return *this; 

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

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

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(); >
my buffer your buffer 

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

Тип this указателя изменяется в зависимости от того, включает const ли объявление функции и (или) volatile ключевое слово. Следующий синтаксис описывает тип this функции-члена:

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

Декларатор функции-члена определяет cv-qualifier-list . Это может быть const или volatile (или оба). class-type — имя classобъекта .

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

Объявление функции-члена тип указателя this для именованного class myClass
void Func() myClass *
void Func() const const myClass *
void Func() volatile volatile myClass *
void Func() const volatile const volatile myClass *

В следующей таблице описаны дополнительные сведения и const "volatile".

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

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

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

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

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

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *