1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
1

Указатель this, теория

23.03.2017, 12:53. Показов 4956. Ответов 80
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
9.3.2 The this pointer [class.this]
The type of this in a member function of a class X is X*.
Последнее предложение приведённой цитаты чётко ничего не говорит о константности this.

И все говорят о его константности...
указатель this всегда является указателем const и не может быть переназначен
Помогите вникнуть. Я чего-то недопонял. Не, ну я принимал второе, а тут прочёл, и.. не врубился.
2
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.03.2017, 12:53
Ответы с готовыми решениями:

Как получить ссылку на указатель или указатель на указатель в массиве?
В процессе реализации сортировки пузырьком натолкнулся на такую проблему: как поменять значения...

Указатель типа void. Использование косвенного связывания через универсальный указатель
Необходимо использовать косвенного связывания через универсальный указатель, примерный вид: struct...

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

Функция, получающая указатель на обычную функцию, получает указатель на метод класса
Здравтсвуйте. Имеется вопрос по указателям на методы класса. Допустим, есть функция( f ), которая...

80
rikimaru2013
23.03.2017, 22:23     Указатель this, теория
  #41

Не по теме:

Цитата Сообщение от Croessmah Посмотреть сообщение
Зависит от устройства random.
:p

Указатель this, теория

1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
23.03.2017, 22:24  [ТС] 42
Константа без квалификатора const.
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
23.03.2017, 22:28 43
hoggy, а какое ваше мнение, что в VS T* const this - майкрософ как всегда?
0
Вездепух
Эксперт CЭксперт С++
11691 / 6370 / 1723
Регистрация: 18.10.2014
Сообщений: 16,052
23.03.2017, 22:28 44
Цитата Сообщение от hoggy Посмотреть сообщение
prvalue и есть временные объекты.
Prvalue - это результаты выражений, которые либо являются временными объектами, либо вообще не ассоциированы ни с какими объектами.

Например, результат выражения 3+2 - prvalue, которое не является временным объектом, а как раз является "просто значением" не ассоциированным ни с какими объектом.
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
23.03.2017, 22:30  [ТС] 45
rikimaru2013, это ведь как раз не будет константой времени компиляции. 4 не будет известно на стадии компиляции. Только после.
0
Вездепух
Эксперт CЭксперт С++
11691 / 6370 / 1723
Регистрация: 18.10.2014
Сообщений: 16,052
23.03.2017, 22:32 46
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
в VS T* const this - майкрософ как всегда?
Это откуда такие сведения?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <type_traits>
 
struct S
{
  void foo()
  {
    std::cout << std::is_same<decltype(this), S *>::value << std::endl;
    std::cout << std::is_same<decltype(this), S *const>::value << std::endl;
  }
};
 
int main()
{
  S().foo();
}
Код
1
0
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
23.03.2017, 22:36 47
Цитата Сообщение от daslex Посмотреть сообщение
это ведь как раз не будет константой времени компиляции. 4 не будет известно на стадии компиляции. Только после.
Картинка не моя) А говорим про это http://rextester.com/RAHO66470

Добавлено через 1 минуту
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Это откуда такие сведения?
скриншоты на 1 странице
0
daslex
23.03.2017, 22:45  [ТС]
  #48

Не по теме:

rikimaru2013, Да я тут стараюсь добиться точности)
Точность очень важна.

Это тот же случай, где точность влияет на информированность: догадайся, мол сам, а на самом деле маленькая неточность, способная ввести неумех в заблуждение. Я знаю, что речь о constexpr, просто думаю, что иногда имеет смысл быть точнее. Вот не знал бы я, а потом наступил на грабли, потом бы искал ответ, лез бы в форумы, почему, мол, не получается скромный массив создать. И что-то в этом духе обязательно бы случилось. Давным-давно как раз и лез с этим вопросом на этот форум.

0
Вездепух
Эксперт CЭксперт С++
11691 / 6370 / 1723
Регистрация: 18.10.2014
Сообщений: 16,052
23.03.2017, 23:00 49
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
скриншоты на 1 странице
Ну всякие там "всплывающие GUI подсказки" в IDE вообще ничего не значат. Микрософтовский компилятор не считает this const-квалифицированным.

Тут, кстати, важно то, что кроме как в decltype, нигде в С++ невозможно определить на уровне языка, считает ли компилятор указатель this const-квалифицированным или нет. Поэтому если какому-то компилятору захотелось внутренне рассматривать указатель this как const-квалифицированный (чтобы предотвратить попытки модификации например), то он имеет право это делать. Разумеется, не забыв обеспечить правильную функциональность decltype. А когда decltype не было - все вообще было с этим просто.

Компиляторы часто содержат внутренние отклонения от стандарта, которые призваны облегчить из реализацию. Пока такие отклонения не приводят к тому, что правильные программы ведут себя неправильно, ничего страшного в этом нет. Все компиляторы этим содержать такие "упрощения".
3
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
23.03.2017, 23:13  [ТС] 50
Я вернусь к указателю this. В теории, пример, который я напишу ниже, должен быть UB, но учитывая некоторое особое свойство this - неизменяемость+непереназначаемость - этот пример не UB.
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
#include <iostream>
 
using namespace std;
 
class MyClass {
    void erase() {
        delete this;
    }
    void print() {
        cout << "MyClass\n";
    }
 
 
public:
    void init() {
        erase();
        //Тут большой-большой блок функций-членов
        print();
    }
};
 
int main() {
    MyClass *obj = new MyClass;
    obj->init();
}
И как правильно его трактовать?

Ведь если он UB, то это обозначает, что косвенно изменить указатель this можно. Все признаки UB у примера есть. Если косвенно изменить указатель this можно, то, значит, утверждение, что this не может быть переназначен - неверно.
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
23.03.2017, 23:23 51
daslex, учитывая, что в теме TheCalligrapher, мне лучше молчать и не вякать с моими 19 мес опыта, но всё же в вашем примере нету UB.

UB в данном коде мог бы быть если шло бы обращение к данным, которые были delete - учитывая, что в print нету обращения к полям - нету UB. Моё мнение)
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
23.03.2017, 23:39  [ТС] 52
Я, конечно, подожду ответа специалистов.
Но моё мнение такое, что если память не зарезервирована, то любое выделение памяти может схватить тот самый адрес, где однажды лежал удалённый ныне указатель this, таким образом может произойти несанкционированное переписывание this, что и будет тем самым переназначением, ведь память может выделиться как раз для начала нового объекта, другого объекта, и this в конфузе. Как-то так.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.03.2017, 23:42 53
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
а какое ваше мнение, что в VS T* const this - майкрософ как всегда?
у cl все так же, как и gcc, и тд
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
23.03.2017, 23:43  [ТС] 54
Да. Наверное не UB.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.03.2017, 23:47 55
Цитата Сообщение от daslex Посмотреть сообщение
Ведь если он UB, то это обозначает, что косвенно изменить указатель this можно.
формально это - ub.
работа идёт с неконсистентным объектом.
однако, сам this при этом не изменился.
он по прежнему указывает на уже убитый объект.
http://rextester.com/RGH21047
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
#include <iostream>
 
using namespace std;
 
class MyClass {
    void erase() {
        
        cout << this << endl;
        
        delete this;
        
        cout << this << endl;
    }
    void print() {
        cout << "MyClass\n";
    }
 
 
public:
    void init() {
        erase();
        //Тут большой-большой блок функций-членов
        print();
    }
};
 
int main() {
    MyClass *obj = new MyClass;
    obj->init();
}
delete особождает память по указателю.
но значение самого указателя при этом не изменяется.
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
23.03.2017, 23:51  [ТС] 56
Понял.
0
Вездепух
Эксперт CЭксперт С++
11691 / 6370 / 1723
Регистрация: 18.10.2014
Сообщений: 16,052
23.03.2017, 23:53 57
Цитата Сообщение от daslex Посмотреть сообщение
Ведь если он UB, то это обозначает, что косвенно изменить указатель this можно. Все признаки UB у примера есть. Если косвенно изменить указатель this можно, то, значит, утверждение, что this не может быть переназначен - неверно.
Не совсем понимаю, откуда тут взялось предположение об изменении указателя this. После delete this указатель this становится невалидным. Но это не означает, что его значение поменялось. В этом отношении пример не очень отличается от простого

C++
1
2
int *const p = new int(42);
delete p;
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
23.03.2017, 23:56  [ТС] 58
Утомился.
Я уже разобрался.

Добавлено через 2 минуты
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
После delete this указатель this невалидным
Почему инвалидным-то? Он такой, какой есть, ему не навредишь.
Вас читать немного тяжело, хорошие объяснения, но будто слова глотаются.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
24.03.2017, 00:02 59
Цитата Сообщение от daslex Посмотреть сообщение
Почему инвалидным-то?
инвалидов нельзя разыменовывать.
1
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
24.03.2017, 00:29 60
delete this вообще плохая практика. В большинстве случаев использования, что я встречал - позже кто-нибудь да наступал на грабли.
Но формально, если поменять местами в вашем примере вызов erase (в функции init, ага) и print, то код валиден. Но содержит потенциальную мину замедленного действия. Причём даже обращение к this после удаления может работать как будто всё хорошо. До поры до времени.
1
24.03.2017, 00:29
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.03.2017, 00:29
Помогаю со студенческими работами здесь

Указатель на функцию, которая принимает в качестве параметра указатель на массив
я не понимаю. вроде делаю правильно, но выходит ошибка. есть функция. int foo(int *mas){};...

Как правильно удалять выделенную память под указатель на указатель?
есть код #include &lt;iostream&gt; #include &lt;conio.h&gt; #include &lt;stdlib.h&gt; #include &lt;time.h&gt; using...

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

Реализация двоичных деревьев поиска: Зачем в параметрах функции используется указатель на указатель
Всем привет, встретил в книге такой пример добавления узла в дерево: typedef struct tree {...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru