В этом уроке мы достаточно поверхностно рассмотрим указатель this, чтобы начинающие программисты познакомились с ним и имели представление о том где он встречается и как работает. Хочу, для начала, рассмотреть пару несложных примеров.
В первом будут определены функции: одна из которых будет записывать данные в переменные, а вторая – отображать их на экран. Во втором примере определим класс, який буде містити два методу, выполняющих такую же работу, как и функции из первого примера.
Когда будете рассматривать эти примеры, обратите внимание на то, как функции из первого примера и методы класса из второго примера, будут принимать параметры.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include <iostream> 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; } int main() { setlocale(LC_ALL, "rus"); char name[128] = ""; int age = 0; enterData(name, age); showData(name, age); return 0; } |
В этом примере вы, скорей всего, не увидели ничего нового и сложного для вас. Все просто – функції лише приймають параметри і виконують певні дії з цими параметрами. Теперь напишем простой класс, в якому реалізуємо методи дуже схожі на функції з першого прикладу. Но кое-чем они будут отличаться. А именно тем, что им не надо принимать в виде параметров, члены класса, чтобы внести изменения в них.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include <iostream> using namespace std; class SetShowData { char someName[128]; int someAge; public: void enterData() { cout << "Ваше имя: "; cin.getline(someName, 128); cout << "Ваш возраст: "; cin >> someAge; } void showData() { cout << "\n" << someName << " " << someAge << endl << endl; } }; int main() { setlocale(LC_ALL, "rus"); SetShowData objectOfClass; objectOfClass.enterData(); // вызов метода для ввода данных objectOfClass.showData(); //вызов метода для отображения данных return 0; } |
Рассмотрев этот пример, вы увидели, что определяя методы в теле класса, мы не прописываем параметры в сигнатуре. И вызывая эти методы из главной функции, мы так же не указываем с какими данными им работать. Но каким-то образом данные вносятся именно в те члены класса, які вказані в тілі методів.
Как же методы “понимают”, с какими данными и с каким объектом класса им надо работать? Справа в тому, что в методы класса, неявно передається у вигляді параметра покажчик this (указатель на объект класса). Происходит это автоматически. Мы этого не видим, так как этот указатель – есть скрытый первый параметр любого метода класса.
Указатель this хранит адрес определённого объекта класса. У розглянутому прикладі він зберігає адресу об'єктаobjectOfClass. Таким образом он неявно указывает методам класса с данными какого объекта надо работать.
Отмечу, що у програмістів все ж є можливість застосовувати покажчик this явно. Если бы мы определяли метод enterData() з явним використанням this, это выглядело бы так:
Или так:
Конкретно в этих случаях можно обойтись и без явного использования this. Но иногда явного использования не избежать. К примеру в следующем примере, this не позволит компилятору запутаться в именах членов класса и параметров которые принимает конструктор.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include <iostream> using namespace std; class SetShowData { char someName[128]; int someAge; public: // члены класса и одноименные параметры: SetShowData(char someName[], int someAge) { strcpy_s(this->someName, someName); this->someAge = someAge; } void showData() { cout << "\n" << someName << " " << someAge << endl << endl; } }; int main() { setlocale(LC_ALL, "rus"); SetShowData objectOfClass("Stanislav", 34); objectOfClass.showData(); return 0; } |
В рядку 10 мы определили конструктор с параметрами, имена которых совпадают с именами членов класса: someName і someAge. Далі щоб дати компілятору зрозуміти що саме і куди треба скопіювати, мы явно используем указатель this:
13 | this->someAge = someAge; |
Это означает, що в член класуsomeAge необходимо записать значение, которое будет задано про создании объекта класса.
Подведем итог : Вказівник this – это указатель, который хранит адрес конкретного объекта класса. Он присутствует в виде скрытого первого параметра в каждом методе класса (кроме статических методов). Типом этого указателя является имя класса. В методах класса, при необходимости, можно использовать this явно. Однако явно объявлять, инициализировать или изменять этот указатель, нет возможности.
Надеюсь боле-менее вы разобрались с этой темой. Если есть вопросы – напишіть в коментарях.
І що ж виходить? є this, але можна і оголосити свій покажчик, і використовувати замість this?
Оголосити свій покажчик ви можете, але тільки це буде повний дублікат this, тому ніякого сенсу робити цього немає.
А ось без this ніякого іншого доступу до “цього об'єкту” не було б.
просто, доступно. Спасибо:)
Доброго дня. Спасибо большое за приклад, підкажіть, виходить помилка на вашу коду:
Ошибка (активно)E0289 відсутні екземпляри конструктора “SetShowData::SetShowData”, відповідні списку аргументів типи аргументів: (Const символ [10], int). робив копіпастом. У чому може бути помилка? Спасибо.
Мій теж видає помилку. Мій теж видає помилку. Мій теж видає помилку
Навіщо городити город?
SetShowData(ім'я голець[], INT Вік)
{
strcpy_s(someName, ім'я);
someAge = Вік;
}
Приклад, приклади.
Дата& operator ++()
{
повернутися * цей;
}
Що буде відбуватися в цьому випадку?
Дата& operator ++()
{
повернутися * цей;
}
Що буде відбуватися в цьому випадку?
писати на суржику це круто