2 / 2 / 1
Регистрация: 21.11.2011
Сообщений: 183
|
|||||||||||
1 | |||||||||||
указатели на элементы класса11.09.2012, 18:57. Показов 6905. Ответов 22
Метки нет (Все метки)
Здравствуйте!
есть код:
Вот не могли бы вы поподробней рассказать про то что из себя этот указатель представляет,а то не очень понятно... и есть что-то, что позволяет достать адрес элемента класса, начинается по-моему на __co...и как-то связанно с __thiscall И вообще для чего нужны эти указатели, что на методы класса, что на обычные функции?
0
|
11.09.2012, 18:57 | |
Ответы с готовыми решениями:
22
Указатели и элементы класса Указатели на метод класса Указатели на объекты класса Указатели на члены класса |
11.09.2012, 19:14 | 2 |
Указатель на поле класса/структуры Foo это не *, а Foo::*.
Чтобы получить значение по этому указателю, помимо него самого нужен еще указатель на экземпляр объекта Foo. Указатели на функции нужны для более гибкого, настраиваемого поведения. Например сортировка, передал указатель на один предикат - отсортировал по возрастанию, другой - по убыванию, и так далее. Так указатели на функции нужны для обратных вызовов. В общем, применений много.
0
|
2 / 2 / 1
Регистрация: 21.11.2011
Сообщений: 183
|
|
11.09.2012, 19:27 [ТС] | 3 |
Ну для этого же я могу передавать не указатель на функцию, а саму функцию...
можете какой-нибудь простенький пример-код привести, где невозможно обойтись без указателя на функцию/метод?
0
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
|
11.09.2012, 19:37 | 4 |
Alberto_Timakov,
0
|
11.09.2012, 19:44 | 5 | ||||||||||||||||||||
Пример 1: создание окна средствами WinAPI
Пример 2: сортировка контейнера
P.S. Сказанное относится только к указателям на обычные функции, с указателем на метод такое не прокатит, для его вызова вообще синтаксис особый, с использованием ->*, а чтобы создать такой указатель оператор & обязателен.
1
|
2 / 2 / 1
Регистрация: 21.11.2011
Сообщений: 183
|
||||||
11.09.2012, 21:07 [ТС] | 6 | |||||
я имел ввиду
Ну т.е. конечно глупость сморозил, т.к. передается значение, а не функция. - спасибо за пример Добавлено через 2 минуты не мог ли кто-нибудь поподробней о том что он из себя представляет...вот эту фразу развернуть...
0
|
11.09.2012, 21:23 | 7 | |||||
Можно посмотреть на это с другой стороны - любому методу экземпляра (то бишь нестатическому) неявно передается указатель на экземпляр (this), поэтому при отсутствии экземпляра тебе не достает одного параметра для передачи его методу. Скобочки вокруг выражения типа (object.*memberPtr)() или (objectPtr->*memberPtr)() приходится ставить, чтобы разрешить неоднозначность в грамматике C++.
0
|
Комп_Оратор)
|
|
11.09.2012, 21:25 | 8 |
Alberto_Timakov, это логично. Ведь экземпляр класса это по сути шаблон структуры данных. Методы не создаются заново, они существуют в единственном экземпляре с момента объявления класса (не экземпляра). Посему доступ к ним можно получить либо через класс с разрешением доступа от его имени, либо через экземпляр (но тут нужно понимать, что в экземпляре то их нет и быть не может). То есть адрес метода это смещение на код в классе. Поэтому к адресу экземпляра, он не имеет прямого отношения и для доступа к нему запускается механизм доступа к классу.
0
|
2 / 2 / 1
Регистрация: 21.11.2011
Сообщений: 183
|
|
11.09.2012, 21:29 [ТС] | 9 |
0
|
11.09.2012, 21:36 | 10 | |||||
0
|
Комп_Оратор)
|
|
11.09.2012, 21:41 | 11 |
Неуклюжая конечно фраза. Я не имел ввиду что класс это место где последовательно уложены методы.
Методы класса - достояние класса и их адрес получается в конечном счёте через класс (тип данных и связанных с ними методов), а не через экземпляр - переменную класса (типа). Хотя в записи это может выглядеть именно так.
1
|
2 / 2 / 1
Регистрация: 21.11.2011
Сообщений: 183
|
|
11.09.2012, 21:44 [ТС] | 12 |
Герцто, что у тебя после кода, я каким то образом пропустил. Спасибо=))
0
|
~ Эврика! ~
1256 / 1005 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
|
|
11.09.2012, 22:46 | 14 |
1
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
11.09.2012, 22:56 | 15 |
~OhMyGodSoLong~, виртуальные таблицы используются только при динамическом связывании. При статическом все вычисляет компилятор во время компиляции.
0
|
11.09.2012, 23:58 | 16 |
http://liveworkspace.org/code/... 255f346c27 При появлении виртуальной функции размер пустого класса возрос с 1 байта до 4, то есть как раз на размер указателя на vtable для 32-битной машины.
0
|
Комп_Оратор)
|
|
12.09.2012, 00:12 | 17 |
Наверное и невиртуальные методы могут адресоваться посредством таблицы. Для меня важно, что это функции, то есть их указатель - указатель на функцию возвращающую значение типа... и объявляющую аргументы типа..., и это не простой указатель на встроенный тип. Целая структура. Вдобавок (и главное, если речь о методе), - он связан с классом. Нестатический метод без экземпляра вызвать нельзя, поскольку без указателя на экземпляр (this) нет доступа к полям. Но сути это не меняет. Ведь this в этом случае передается, не для того, чтобы метод найти, а для того чтобы указать методу класса, к полям какого экземпляра ему обращаться.
0
|
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
|
||||||
12.09.2012, 04:06 | 18 | |||||
Если подумать, то для вызова невиртуального метода через указатель,
живой объект не очень то и нужен. Ведь не нужно шарится по таблице виртуальных функция для поиска правильной функции. С указателем на виртуальный метод совсем другое, потому что таблица виртуальных функция находится по смещению относительно адреса объекта, для которого этот метод зовется. Что стандарт говорит относительно первого утверждения - хз, но студия и компилер из ссылки делают вызов невиртуального метода имея нулевой указатель на объект. То, что в методе this оказывается равным нулю - это уже отдельная история. Если к полям класса не обращатся, ничего не упадет. http://liveworkspace.org/code/... 92b61a7bfd Далее, вот например указатель на метод: typedef void (Foo::*MethodPtr)(); Тут нигде не кодируется его виртуальность\невиртуальность. Поэтому, можно прикинуть, что компиляторы реализуют указатели на методы в виде какой-то структуры, в которой есть флажок о виртуальности\невиртуальности метода и другие поля, позволяющие сделать правильный вызов. Для невиртуальных методов будет использоваться поле, в которой указатель на метод похож на указатели на свободные функции (с учетом того, что сигнатура несколько расширена за счет неявной передачи this и может быть соглашения о вызове другие). А вот в случае указателя на виртулальный метод используются другие поля. Например просто индекс функции в таблице виртуальных функций, ведь для вызова виртуального метода через указатель нужен сам объект для определения, где таблица функций и смещение на указатель к нужному методу. Ну примерно это можно было бы описать так:
0
|
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
|
||||||
12.09.2012, 04:06 | 19 | |||||
Если подумать, то для вызова невиртуального метода через указатель,
живой объект не очень то и нужен. Ведь не нужно шарится по таблице виртуальных функция для поиска правильной функции. С указателем на виртуальный метод совсем другое, потому что таблица виртуальных функция находится по смещению относительно адреса объекта, для которого этот метод зовется. Что стандарт говорит относительно первого утверждения - хз, но студия и компилер из ссылки делают вызов невиртуального метода имея нулевой указатель на объект. То, что в методе this оказывается равным нулю - это уже отдельная история. Если к полям класса не обращатся, ничего не упадет. http://liveworkspace.org/code/... 92b61a7bfd Далее, вот например указатель на метод: typedef void (Foo::*MethodPtr)(); Тут нигде не кодируется его виртуальность\невиртуальность. Поэтому, можно прикинуть, что компиляторы реализуют указатели на методы в виде какой-то структуры, в которой есть флажок о виртуальности\невиртуальности метода и другие поля, позволяющие сделать правильный вызов. Для невиртуальных методов будет использоваться поле, в которой указатель на метод похож на указатели на свободные функции (с учетом того, что сигнатура несколько расширена за счет неявной передачи this и может быть соглашения о вызове другие). А вот в случае указателя на виртулальный метод используются другие поля. Например просто индекс функции в таблице виртуальных функций, ведь для вызова виртуального метода через указатель нужен сам объект для определения, где таблица функций и смещение в этой таблице чтобы получить указатель на правильную функцию. Флажок виртуальности\невиртуальности проверяется в рантайме. Ну примерно это можно было бы описать так:
1
|
Комп_Оратор)
|
|
12.09.2012, 13:56 | 20 |
DU, я совсем не уверен в том, что сейчас скажу. Но есть надежда, что если кого-то зацепит, - получим более конкретную информацию.
С моей точки зрения объект наследующего класса, объявленный через указатель базового класса не теряет ведь, своей типовой принадлежности (конструктор же свой используется), поэтому информация о смещении, в данном случае находится в базовом классе. В экземпляре, - информация о том относительно какого класса (наследника) смещение, ну и конечно this... Не по теме:
Простите за оффтоп:friends:
0
|
12.09.2012, 13:56 | |
12.09.2012, 13:56 | |
Помогаю со студенческими работами здесь
20
Конструкторы и указатели на объект класса ООП - Указатели на функции члены класса Потоки и указатели (в поток вставить объект класса) Как на практике используются указатели на члены класса Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |