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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.92
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
#1

указатели на элементы класса - C++

11.09.2012, 18:57. Просмотров 1771. Ответов 22
Метки нет (Все метки)

Здравствуйте!
есть код:

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
class A
{
    public:
    void C(void){return;}
        static int D(void){return 0;}
    int a;
        static int d;
};
 
int main(int argc, char** argv)
{
        A a_obj;
    int (A:: *p)= &A::a;// - работает
        //int *p= &a_obj.a; - не работает
        //int *p= &A::a; - не работает
        void (A::*f)(void)= &A::C; // - работает
        //void (*f)(void)= &A::C; - Не работает
        //void (*f)(void)= &a_obj.C; - Не работает
        int *e1= &a_obj.a;// - Работает
        int *e2= &A::a;// - Работает
        int (*F1)(void)= &A::D;// - работает
        int (*F2)(void)= &a_obj.D;// - работает
    system("Pause");
    return 0;
}
Знаю, что в не статическую функцию Неявно передается this, т.е. выходит вместо параметра (void), по сути параметр (this) в методе C и т.к. преобразование из в void (A::*)() в void * невозможно, то ошибка, а как тогда объяснить ошибку связанную со строкой :
C++
1
2
3
  
      //int *p= &a_obj.a; - не работает
        //int *p= &A::a; - не работает
в Т.А. Павловская "C/C++ прог. на яз. высокого уровня" пишут, что указатель на элемент класса в отличии от указателя на обычную переменную или функцию, ссылается не на определенный адрес памяти, а больше похож на индекс в массиве, т.к. задает смещение

Вот не могли бы вы поподробней рассказать про то что из себя этот указатель представляет,а то не очень понятно... и есть что-то, что позволяет достать адрес элемента класса, начинается по-моему на __co...и как-то связанно с __thiscall

И вообще для чего нужны эти указатели, что на методы класса, что на обычные функции?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.09.2012, 18:57     указатели на элементы класса
Посмотрите здесь:

Указатели и элементы класса - C++
Суть проблемы: есть класс neuro. в нём есть элемент данных double *inputs; // входыесть независимый от первого класс auction в нём...

Указатели на члены класса - C++
Здравствуйте, В коде при вызове функции print() из CL2 вызывается print() из CL1. Подскажите, где грабли. Заранее спасибо. ...

Указатели на метод класса - C++
Допустим есть 2 класса: class A { public: A() {} ~A() {} virtual void Draw(GLuint shader)

Указатели на объекты класса - C++
Здравствуйте. помогите новичку. есть проблема с освоением программирования на VC++. пытаюсь скомпилировать вот этот пример из книги: ...

Конструкторы и указатели на объект класса - C++
Добрый вечер. Помогите, пожалуйста, прояснить 2 вещи: 1) В чём будет отличие между конструкторами: int a; //Исп. оператор...

Потоки и указатели (в поток вставить объект класса) - C++
Есть структура: class shapka{ public: int* prev; int n; int* next; } }; Нужно в поток вставить объект класса, потом...

Как на практике используются указатели на члены класса - C++
Вопрос №3. А как на практике используются указатели на члены класса? Они в реальном коде вообще используется? Приведите пример когда они...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
11.09.2012, 19:14     указатели на элементы класса #2
Указатель на поле класса/структуры Foo это не *, а Foo::*.
Чтобы получить значение по этому указателю, помимо него самого нужен еще указатель на экземпляр объекта Foo.
Указатели на функции нужны для более гибкого, настраиваемого поведения. Например сортировка, передал указатель на один предикат - отсортировал по возрастанию, другой - по убыванию, и так далее.
Так указатели на функции нужны для обратных вызовов.
В общем, применений много.
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
11.09.2012, 19:27  [ТС]     указатели на элементы класса #3
Цитата Сообщение от Герц Посмотреть сообщение
Например сортировка, передал указатель на один предикат - отсортировал по возрастанию, другой - по убыванию, и так далее.
Ну для этого же я могу передавать не указатель на функцию, а саму функцию...

можете какой-нибудь простенький пример-код привести, где невозможно обойтись без указателя на функцию/метод?
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
11.09.2012, 19:37     указатели на элементы класса #4
Alberto_Timakov,
а саму функцию
Простите, что? Это как же вы саму функцию передадите в другую функцию как параметр?
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
11.09.2012, 19:44     указатели на элементы класса #5
Ну для этого же я могу передавать не указатель на функцию, а саму функцию...
Как это, как это?

Пример 1: создание окна средствами WinAPI
C++
1
2
3
4
5
6
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 
// ...
 
WNDCLASSEX wcex;
wcex.lpfnWndProc = WndProc;
Ты никак, при всем желании, не обойдешься без передачи указателя на функцию WndProc, если хочешь задать своему окну какое-то поведение. Система должна знать, к кому ей взывать, когда окну приходит сообщение :-)

Пример 2: сортировка контейнера
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
#include <vector>
#include <algorithm>
#include <iostream>
 
bool predicate( int a, int b );
 
int main()
{
   std::vector< int > vec = { 1, 0, 3, -1, 10, 5, 16, 20, 2 };
   
   for ( std::vector< int >::iterator it = vec.begin(); it != vec.end(); ++it ) {
      std::cout << *it << ' ';
   }
   std::cout << std::endl;
 
   std::sort( vec.begin(), vec.end(), predicate );   
 
   for ( std::vector< int >::iterator it = vec.begin(); it != vec.end(); ++it ) {
      std::cout << *it << ' ';
   }
   std::cout << std::endl;
   
   return 0;
}
 
bool predicate( int a, int b )
{
   return a < b;
}
Простите, что? Это как же вы саму функцию передадите в другую функцию как параметр?
Хотя тут все понятно. C++ не требует наличия операции взятия адреса на функцию, то есть записи
C++
1
2
void (*funcPtr)() = func;
void (*funcPtr2)() = &func;
эквивалентны. То же относится и к вызову функции по указателю, не обязательно его разыменовывать:
C++
1
2
funcPtr();
(*funcPtr)();
так же эквивалентные записи.

P.S. Сказанное относится только к указателям на обычные функции, с указателем на метод такое не прокатит, для его вызова вообще синтаксис особый, с использованием ->*, а чтобы создать такой указатель оператор & обязателен.
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
11.09.2012, 21:07  [ТС]     указатели на элементы класса #6
Цитата Сообщение от ForEveR Посмотреть сообщение
Простите, что? Это как же вы саму функцию передадите в другую функцию как параметр?
я имел ввиду

C++
1
2
3
4
5
6
7
8
int f(int a){return a;}
 
void F(int val){return val;}
 
int main(void)
{
   F(f(1)); // Передаю функцию ^_^
}

Ну т.е. конечно глупость сморозил, т.к. передается значение, а не функция.
Цитата Сообщение от Герц Посмотреть сообщение
std::sort( vec.begin(), vec.end(), predicate );
- спасибо за пример

Добавлено через 2 минуты
Цитата Сообщение от Alberto_Timakov Посмотреть сообщение
указатель на метод больше похож на индекс в массиве, т.к. задает смещение
не мог ли кто-нибудь поподробней о том что он из себя представляет...вот эту фразу развернуть...
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
11.09.2012, 21:23     указатели на элементы класса #7
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>
 
class Foo
{ 
public:
   void a() { std::cout << "Foo::a()" << std::endl; }
};
 
void invokeMember( Foo* foo, void( Foo::* ptr )() )
{
   (foo->*ptr)(); // Вызов метода по указателю на экземпляр класса и указателю на метод
}
 
int main()
{
   Foo foo;
 
 
   invokeMember( &foo, &Foo::a );
 
   void ( Foo::* ptr )() = &Foo::a;
   (foo.*ptr)(); // Вызов метода по указателю на экземпляре объекта
     
   return 0;
}
Указатель на метод в действительности является смещением относительно адреса начала класса. Поэтому тебе нужен экземпляр объекта (или указатель на него), к которому это смещение можно применить, чтобы найти нужный метод.
Можно посмотреть на это с другой стороны - любому методу экземпляра (то бишь нестатическому) неявно передается указатель на экземпляр (this), поэтому при отсутствии экземпляра тебе не достает одного параметра для передачи его методу.

Скобочки вокруг выражения типа (object.*memberPtr)() или (objectPtr->*memberPtr)() приходится ставить, чтобы разрешить неоднозначность в грамматике C++.
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6443 / 3082 / 306
Регистрация: 04.12.2011
Сообщений: 8,488
Записей в блоге: 4
11.09.2012, 21:25     указатели на элементы класса #8
Цитата Сообщение от Alberto_Timakov Посмотреть сообщение
я имел ввиду
не мог ли кто-нибудь поподробней о том что он из себя представляет...вот эту фразу развернуть...
Alberto_Timakov, это логично. Ведь экземпляр класса это по сути шаблон структуры данных. Методы не создаются заново, они существуют в единственном экземпляре с момента объявления класса (не экземпляра). Посему доступ к ним можно получить либо через класс с разрешением доступа от его имени, либо через экземпляр (но тут нужно понимать, что в экземпляре то их нет и быть не может). То есть адрес метода это смещение на код в классе. Поэтому к адресу экземпляра, он не имеет прямого отношения и для доступа к нему запускается механизм доступа к классу.
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
11.09.2012, 21:29  [ТС]     указатели на элементы класса #9
Цитата Сообщение от IGPIGP Посмотреть сообщение
То есть адрес метода это смещение на код в классе.
Что значит смещение на код в классе?
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
11.09.2012, 21:36     указатели на элементы класса #10
Что значит смещение на код в классе?
Я тебе пример привел на пару постов выше.
Методы не создаются заново, они существуют в единственном экземпляре с момента объявления класса (не экземпляра).
Кстати недавно разузнавал про этот вопрос, заметив возможность кода вида:
C++
1
2
Foo* foo = NULL;
foo->bar();
Оказалось, что стандарт не обязывает хранить методы в единственном экземпляре, хоть это и логично.
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6443 / 3082 / 306
Регистрация: 04.12.2011
Сообщений: 8,488
Записей в блоге: 4
11.09.2012, 21:41     указатели на элементы класса #11
Цитата Сообщение от Alberto_Timakov Посмотреть сообщение
Что значит смещение на код в классе?
Неуклюжая конечно фраза. Я не имел ввиду что класс это место где последовательно уложены методы.
Методы класса - достояние класса и их адрес получается в конечном счёте через класс (тип данных и связанных с ними методов), а не через экземпляр - переменную класса (типа). Хотя в записи это может выглядеть именно так.
Alberto_Timakov
1 / 1 / 0
Регистрация: 21.11.2011
Сообщений: 183
11.09.2012, 21:44  [ТС]     указатели на элементы класса #12
Герцто, что у тебя после кода, я каким то образом пропустил. Спасибо=))
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
11.09.2012, 21:48     указатели на элементы класса #13
Методы класса - достояние класса и их адрес получается в конечном счёте через класс (тип данных и связанных с ними методов), а не через экземпляр - переменную класса (типа).
Статические - несомненно, они так и называются. А вот относительно нестатических стандарт умалчивает, хоть я и не видел компилятора, создающего для каждого экземпляра свои методы.
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
11.09.2012, 22:46     указатели на элементы класса #14
Цитата Сообщение от IGPIGP Посмотреть сообщение
Методы класса - достояние класса и их адрес получается в конечном счёте через класс (тип данных и связанных с ними методов), а не через экземпляр - переменную класса (типа). Хотя в записи это может выглядеть именно так.
Кодовые слова: таблица виртуальных функций.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.09.2012, 22:56     указатели на элементы класса
Еще ссылки по теме:

Указатели и классы: присвоение значения элементу массива, который является полем класса - C++
Доброго времени суток, делал задание, где надо создать класс, полем которого будет массив указателей на другие массивы и перегрузить...

Не вводятся элементы в массив(указатели) - C++
Здравствуйте! У меня возникла проблема с указателями... Я хочу сделать функцию, которая организует ввод данных в статический массив, и...

Просуммировать элементы массива используя указатели - C++
III. Создайте 5 елементный статический массив переменных типа int и заполните его произвольными значениями. Затем создайте указатель,...

Указатели: сдвинуть элементы циклически на 1 позицию влево - C++
Условие задачи: Заполните случайным образом одномерный массив из n элементов и здвиньте элементы циклически на 1 позицию влево. (Например...

Вывести на экран элементы массива используя указатели - C++
здравстуйте!Создать одномерный массив состоящий из случайных целых чисел. Вывести на экран элементы массива используя указатели без прямого...


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

Или воспользуйтесь поиском по форуму:
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
11.09.2012, 22:56     указатели на элементы класса #15
~OhMyGodSoLong~, виртуальные таблицы используются только при динамическом связывании. При статическом все вычисляет компилятор во время компиляции.
Yandex
Объявления
11.09.2012, 22:56     указатели на элементы класса
Ответ Создать тему
Опции темы

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