Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.64
VLK
193 / 162 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
#1

указатель this что именно он делает - C++

25.05.2013, 15:32. Просмотров 1496. Ответов 28
Метки нет (Все метки)

Вот код:

Кликните здесь для просмотра всего текста
C++
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
#include <iostream>
 
class test_class
{
public:
void set_var(int a, int b) { varOne = a; varTwo = b; }
test_class operator++() { varOne++; varTwo++; return *this; }
int get_varOne() { return varOne; }
int get_varTwo() { return varTwo; }
    
private:
int varOne;
int varTwo;
};
 
int main()
{
test_class qwerty;
qwerty.set_var(0,10);
    
std::cout << "varOne: " << qwerty.get_varOne() << "\n";
std::cout << "varTwo: " << qwerty.get_varTwo() << "\n";
 
qwerty++;
std::cout << "varOne: " << qwerty.get_varOne() << "\n";
std::cout << "varTwo: " << qwerty.get_varTwo() << "\n";
qwerty++;
std::cout << "varOne: " << qwerty.get_varOne() << "\n";
std::cout << "varTwo: " << qwerty.get_varTwo() << "\n";
        
system("pause");
return 0;
}


Много прочитал про оператор this, но все же осталось смутное представление о нем, думаю на практике, на примере, удастся понять до конца, подскажите, в строчке 7 часть кода: return *this куда именно и что именно возвращает оператор return ?

Правильно ли я понимаю, что return *this возвращает новое значение двух переменных (varOne и varTwo), по тому адресу, по которому они находятся? в объекте qwerty?
т.е. сначала они ( переменные varOne и varTwo) были 0 и 10, и находились по адресам, допустим varOne - 00001, varTwo - 00002, после выполнения операции инкремента, в эти адреса (00001 и 00002) return *this возвращает новые значения, 1 и 11?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.05.2013, 15:32
Здравствуйте! Я подобрал для вас темы с ответами на вопрос указатель this что именно он делает (C++):

обьясните что именно делает функция this - C++
Обьяснте пожалуйста что делает функция this?

Объясните что именно делает функция даном коде - C++
Помогите пожалуйста. Я не могу понять что делает функция которая стоит вначале моего кода, точнее я немогу понять почему там k&lt;=N/2. Ниже...

Объясните что именно делает "x%d, y%d: " или что это в даном коде - C++
#include &lt;iostream&gt; #include &lt;cmath&gt; using namespace std; double rast(double x1, double y1, double x2, double y2) // Функція яка...

Что в программе делает так, что процессор грузится на 100%? - C++
Я не очень разбираюсь в С++, поэтому прошу вашей подсказки по поводу нагрузки на процессор. Вот код программы, на компьютере жрет всю...

Что это за знак >> прочитал что это сдвиг вправо? что он делает - C++
int d=6, c=5,f; f = d &gt;&gt; c; cout&lt;&lt; f; вывод 0

Что это за метод?И что он делает? - C++
double func (double y, int k, int n){ double y1; for (int i=0; i&lt;=n+1;i++) y1=0; double t; t=0; y1=1; ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
VLK
193 / 162 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
26.05.2013, 00:06  [ТС] #16
C++
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
#include <iostream>
 
class test
{
public:
int v;
};
 
test inc(test* const this_, int inc_value)
{
test rv = *this_;
this_->v += inc_value;
return rv;
}
 
int main()
{
test a;
a.v = 10;
 
test b = inc(&a, 1);
 
std::cout << "a.v = " << a.v << std::endl;
std::cout << "b.v = " << b.v << std::endl;
 
system("pause");
return 0;
}

Строчки 3-7 объявляется класс test, у него одна открытая переменная "v".


в Строчке 18 объявляется объект "a" класса "test", и переменной "v" присваивается значение 10.

в Строчке 21 объявляется еще один объект "b" класса "test", и ему присваивается значение которое рассчитывается в функции строчки 9-14

В строчке 9 объявляется функция "inc" типа "test", с параметрами, 1. параметр это ссылка на объект "a" класса "test", второй целочисленное число.

В строке 11 объявляется объект "rv" класса "test", все его параметры равны параметрам this_, а в свою очередь его параметры равны объекту "a" класса "test", this_ это ссылка на объект "a", Но объект "rv" имеют свой адрес в области памяти, отличный от "a", а "test* const this_" и "a" имеют один адрес в области памяти.

В строке 12 к "v" через указатель прибавляется "inc_value", но эта "v" имеет отношение к "test* const this_" из строчки 9, а не к объекту "rv"

т.е. 12 строчка поменяла значение "a.v" на 11
При это "b.v" остается 10 т.к. он имеет разный адрес в памяти от "a.v" и "test* const this_"

Все правильно?

и еще вопрос насчет строчки 13, на сколько мне известно оператор return возвращает только значение, число или лог. значение, а тут получается объект класса, я может не в полном объеме понимаю

Я представляю так? вернуть можно значение, например:

int x=10;
return x;

а тут, для меня это равнозначно:

return funciya();
или
return int x;

но так же не может быть, где ошибка в моей логике?
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
26.05.2013, 00:20 #17
Цитата Сообщение от VLK Посмотреть сообщение
т.е. 12 строчка поменяла значение "a.v" на 11
При это "b.v" остается 10 т.к. он имеет разный адрес в памяти от "a.v" и "test* const this_"

Все правильно?
b остался таким потому, что вы ему присвоили старое значение a, которое вернулось из функции, где вы его вначале скопировали через переданный указатель в локальную переменную.

Цитата Сообщение от VLK Посмотреть сообщение
и еще вопрос насчет строчки 13, на сколько мне известно оператор return возвращает только значение, число или лог. значение, а тут получается объект класса, я может не в полном объеме понимаю
Всё правильно. Функции возвращают значения. Объекты класса тоже могут быть значениями. Главное свойство значений: их можно копировать (иногда ещё присваивать можно). Поэтому у объектов-значений должен быть конструктор копирования, чтобы они вели себя как значения. В том числе чтобы они возвращались из функций. Конструктор копирования обязательно существует у каждого класса; если не явно написанный вами, то сгенерированный компилятором автоматически (однако его использование может быть запрещено или ограничено). Автоматически сгенерированный тупо копирует все поля из одного объекта в другой. Кроме того, иногда функции должны не возвращать копию объекта, а создать объект где-то вне функции. В Си++ для этого ввели специальную приблуду rvalue, а до этого перебивались out-параметрами, оптимизациями компилятора или писали объекты (или обёртки) так, чтобы не было разницы между копированием и перемещением объекта.
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6447 / 3094 / 306
Регистрация: 04.12.2011
Сообщений: 8,567
Записей в блоге: 4
26.05.2013, 00:37 #18
VLK, то что делает функция inc лучше сделать по-другому. Перегрузите постфиксный оператор operator++()
тогда:
C++
1
2
3
4
5
6
7
8
9
10
int main()
{
test a;
a.v = 10;
test b =a++;
std::cout << "a.v = " << a.v << std::endl;
std::cout << "b.v = " << b.v << std::endl;
system("pause");
return 0;
}
результат тот же, но достигается обычным путём. При возврате ссылки из пост-инкрементного ++, разыменование указателя this не меняет адрес вызывающего объекта, то есть нет нужды передавать константный указатель.
0x10
2460 / 1632 / 238
Регистрация: 24.11.2012
Сообщений: 4,015
26.05.2013, 07:50 #19
IGPIGP, я специально ушел от оператора к функции, чтобы не заморачиваться с префиксной и постфиксной формами и не запутывать еще и ссылками. (Да, выше верно было сказано, что пример инкремента далеко не самый удачный)

Добавлено через 9 минут
Цитата Сообщение от VLK Посмотреть сообщение
В строчке 9 объявляется функция "inc" типа "test", с параметрами, 1. параметр это ссылка на объект "a" класса "test", второй целочисленное число.
Функция inc, которая возвращает объект типа test. Сигнатура функции состоит из двух параметров: константный указатель на объект класса test и целое со знаком.

Цитата Сообщение от VLK Посмотреть сообщение
"test* const this_" и "a" имеют один адрес в области памяти.
this_ и a расположены по разным адресам. При этом в указателе this содержится адрес объекта 'a'.
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6447 / 3094 / 306
Регистрация: 04.12.2011
Сообщений: 8,567
Записей в блоге: 4
26.05.2013, 10:49 #20
Цитата Сообщение от 0x10 Посмотреть сообщение
ушел от оператора к функции, чтобы не заморачиваться с префиксной и постфиксной формами и не запутывать
0x10, совершенно согласен. Я разлил воду именно поэтому. В исходном примере [TC] не указал тип возврата, для оператора и это говорит, что вопрос как возвращается разименованный указатель, - за скобками. Но без этого пример ещё более неудачен, даже не учитывая, что инкремент это оператор-выражение, сочетающее lvalue, rvalue и присваивание. Ну то есть очень неудачный пример для понимания this.

Добавлено через 7 минут
Цитата Сообщение от IGPIGP Посмотреть сообщение
Но как оператор доступа стрелка прижилась.
неправильная конструкция, не прижилась, а осталась!( Она была в С-структурах при доступе через указатель.)

Не по теме:

перечитываю написанное и удивляюсь

OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
26.05.2013, 12:59 #21
Цитата Сообщение от IGPIGP Посмотреть сообщение
неправильная конструкция, не прижилась, а осталась!( Она была в С-структурах при доступе через указатель.)

Не по теме:

Полиморфизм — это неправильно?..

IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6447 / 3094 / 306
Регистрация: 04.12.2011
Сообщений: 8,567
Записей в блоге: 4
26.05.2013, 13:26 #22
OhMyGodSoLong, я написал криво: "стрелка...прижилась"
надо было :"осталась", так как в Си это оператор доступа к членам через указатель на структуру. Совместимость с Си то есть. Про полиморфизм тут не говорил.
VLK
193 / 162 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
26.05.2013, 13:59  [ТС] #23
Кликните здесь для просмотра всего текста
C++
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
35
36
37
38
39
40
41
42
43
44
#include <iostream>
 
class music
{
public:
 
music() {  }
music(int k, int d, int m) { kol = k; dl = d; mb = m; }
~music() {  }
 
void show() { std::cout << "KOL: " << kol << " DL: " << dl << " MB: " << mb << "\n"; }
    
music fun_this(music sss)
{
music temp = sss;
return *this;
}
 
music fun_temp(music vvv)
{
music temp = vvv;
return temp;
}
    
private:
int kol;
int dl;
int mb;
};
 
int main()
{
music a(2,2,2);
a.show();
 
music b = a.fun_this(a);
b.show();
 
music c = a.fun_temp(a);
c.show();
 
system("pause");
return 0;
}


Кажется я начал понимать, указатель this используется только в функциях-членах класса и указывает он на конкретный объект, который есть в функции, т.е. в строке 15 объявляется объект temp и указатель this ссылается именно на него, верно?

Добавлено через 2 минуты
И еще подскажите, я создаю переменную со своим типом, из программы выше music h;, все нормально, я присваиваю ей значение, а как ее вывести на экран, через std::cout не получается
0x10
2460 / 1632 / 238
Регистрация: 24.11.2012
Сообщений: 4,015
26.05.2013, 14:00 #24
VLK, еще раз: this указывает на тот объект, метод которого вызван. Смотрите на строки 34, 37, 40.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.05.2013, 14:00 #25
Цитата Сообщение от VLK Посмотреть сообщение
Кажется я начал понимать, указатель this используется только в функциях-членах класса и указывает он на конкретный объект, который есть в функции, т.е. в строке 15 объявляется объект temp и указатель this ссылается именно на него, верно?
Почти. Только не в одних только функциях-членах, а в функциях-членах и операторах-членах.
VLK
193 / 162 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
26.05.2013, 14:34  [ТС] #26
Цитата Сообщение от 0x10 Посмотреть сообщение
VLK, еще раз: this указывает на тот объект, метод которого вызван. Смотрите на строки 34, 37, 40.
А, вот теперь кажется понял:

Кликните здесь для просмотра всего текста
C++
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
35
36
37
38
39
40
41
#include <iostream>
 
class music
{
public:
 
music() {  }
music(int k, int d, int m) { kol = k; dl = d; mb = m;  }
~music() {  }
 
void show() { std::cout << "KOL: " << kol << " DL: " << dl << " MB: " << mb << "\n"; }
    
music fun_this(music sss)
{
music temp(5,5,5);
return *this;
}
                
private:
int kol;
int dl;
int mb;
};
 
int main()
{
music a(2,2,2);
std::cout << "A(2,2,2) - ";
a.show();
 
music b(3,3,3);
std::cout << "B(3,3,3) - ";
b.show();
 
music c = a.fun_this(a);
std::cout << "C(5,5,5) - ";
c.show();
        
system("pause");
return 0;
}


т.е. в строчке 35 используется для вызова функции-члена объект a и по-этому, в этой функции-члене в строке 16 указатель *this указывает на объект a, а не на temp или какой-нибудь другой. (в сообщении до этого я думал что указатель *this указывает на temp т.к. он создавался в этой функции члене и возвращал его значение, т.е. return temp являлось return*this, но по факту return a является return*this - это про пример в предыдущем сообщении!)
И в данном случае строка 15 бесполезна.

Все правильно?
0x10
2460 / 1632 / 238
Регистрация: 24.11.2012
Сообщений: 4,015
26.05.2013, 14:41 #27
Цитата Сообщение от VLK Посмотреть сообщение
по факту return a является return*this
Вот этого не понял, остальное вроде похоже на правду.
VLK
193 / 162 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
26.05.2013, 14:51  [ТС] #28
Цитата Сообщение от 0x10 Посмотреть сообщение
Вот этого не понял, остальное вроде похоже на правду.
Это конечно не лучший пример
C++
1
2
3
4
5
6
7
8
9
10
11
12
....
music fun_this(music sss)
{
music temp(5,5,5);
return *this;
}
 
....
 
music a(2,2,2);
music c = a.fun_this(a);
....
Я считал что return *this будет равнозначен return temp т.е. music c будет равен music c(5,5,5), но на самом деле, из-за того, что мы используем для вызова функции-члена объект a то *this указывает именно на a и в итоге получается что return a равнозначен return*this, и в итоге music c будет равен music c(2,2,2)

Моя ошибка была в том, что я думал что указатель *this указывает на объект созданный в функции (в данном случае temp), но он указывает на тот объект при помощи которого была вызвана данная функция (в данном случае a).

Только не спрашивайте как мне этот бред мог прийти в голову
т.к. это по крайне мере не логично, потому что в функции-члене может создаваться несколько объектов и на какой тогда указывать..
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6447 / 3094 / 306
Регистрация: 04.12.2011
Сообщений: 8,567
Записей в блоге: 4
26.05.2013, 18:23 #29
VLK, вызывающий объект это переменная класса от которой через точку (оператор доступа) вызывается функция-член. this внутри этой функции - указатель на эту переменную (экземпляр). Что касается разыменования this при возврате, то результат зависит от типа возврата (объявленного в сигнатуре метода). Вы продолжаете его не писать и похоже не видите разницы. Вот тут я понаписывал опять, может разберёте:
//
C++
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <iostream>
using namespace std;
class music
{
public:
music() {  }
music(int k, int d, int m) { kol = k; dl = d; mb = m;  }
~music() {  }
void show() {cout<<"KOL: "<<kol<<" DL: "<<dl<<" MB: "<<mb<<"\n"; }
music fun_this(music sss)//вернет music 
{
music temp(5,5,5);//этот объект просто будет уничтожен при выходе из функции 
return *this;//это новый объект (копия вызывающего создастся при присвоении), так как возвращается объект типа music
}
music& ref_fun_this()//вернет music& - ссылку ЭТОТ ПРИМЕР САМЫЙ НУЖНЫЙ см. историю про c и d остальное - варианты
{
return *this;//это ссылка на сам вызывающий объект, а не копия так как метод возвращает ссылку
}
music& ref_fun_from_ref(music& isCallingObj)//вернет music& - ссылку 
{
if(&isCallingObj==this) cout<<endl<<"Вызывающий и вызываемый это один объект"<<endl;
else
 cout<<endl<<"Вызывающий и вызываемый это разные объекты"<<endl;
return isCallingObj;//
}
music& ref_fun_from_ptr(music* isCallingObj)//вернет music& - ссылку 
{
if(isCallingObj==this) cout<<endl<<"Вызывающий и вызываемый это один объект"<<endl;
else
 cout<<endl<<"Вызывающий и вызываемый это разные объекты"<<endl;
return *isCallingObj;//
}
//private://это пока не важно
int kol;
int dl;
int mb;
};
int main(){
setlocale (LC_CTYPE, "Russian");
music a(2,2,2);
cout << "A(2,2,2) - ";
a.show();
music b(3,3,3);
cout << "B(3,3,3) - ";
b.show();
cout << endl;
music c = a.fun_this(a);//вернёт копию a то есть с содержит то же, что и a : 2,2,2
a.kol=123;//изменим a
cout << "a(123,2,2) - ";
a.show();
cout << "C(2,2,2) - ";
c.show();cout<<" a изменилась, а c - нет, потому, что с это копия a";
cout << endl;
cout << endl;
music& d = c.ref_fun_this();//вернёт ссылку на c тоесть d и с это один и тот же объект 2,2,2 
c.kol=456;//изменим c
cout << "c(456,2,2) - ";
c.show();
cout << "d(456,2,2)!! - ";
d.show();cout<<" c и d изменились, потому, что d - ссылка на c, то есть то же что и c )";
cout << endl;
music& f = d.ref_fun_from_ref(d);
d.kol=789;//изменим d
cout << "d(789,2,2) - ";
f.show();
cout << "f(789,,2,2) - ";
f.show();cout<<" f и d изменились, потому, что f - ссылка на d, то есть то же что и d )";
cout << endl;
music& g = b.ref_fun_from_ptr( &b );
g.kol=101;//изменим g
cout << "g(101,3,3) - ";
g.show();
cout << "b(101,3,3) - ";
b.show();cout<<" g и b изменились, потому, что g - ссылка на b, то есть то же что и b )";
cout << endl;
cout << endl;
system("pause");
return 0;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.05.2013, 18:23
Привет! Вот еще темы с ответами:

Что значит константный указатель на объект, указатель на константный объект, и как это можно использовать? - C++
Подскажите, что значит константный указатель на объект, указатель на константный объект, и как это можно использовать??

Что именно выполняет эта программа? - C++
Прокоментируйте пожалуйста что происходит в программе со строчки : /*максимальное из чисел, встречающихся в заданной матрице более одного...

Возвращаемое значение. Что именно происходит? - C++
Имеется код класса &quot;Массив&quot;. Реализованы конструктор копии, деструктор, перегрузка операции присваивания и сложение массивов...

Как получить ссылку на указатель или указатель на указатель в массиве? - C++
В процессе реализации сортировки пузырьком натолкнулся на такую проблему: как поменять значения указателей, передаваемых в функцию. Если...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
26.05.2013, 18:23
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru