Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> передача указателя на функцию-член 
:(
    Опции темы
Mormishka
Дата 26.3.2011, 09:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 236
Регистрация: 25.8.2010

Репутация: нет
Всего: нет



Как передать указатель на функцию-член одного класса другому?

Код

typedef int(fun)(int);

class B
{
public:
    fun Myfun;
    B(fun Myfun1)
    {
        this->Myfun=Myfun;
    }
};


class A
{
public:
    B* pB;
    A()
    {
        pB= new B(f);
        this->pB=pB;
    }
    int f(int x)
    {
        return x;
    }
};


Пишет
Код

 error C2659: '=' : overloaded function as left operand

PM MAIL   Вверх
alexvs11
Дата 26.3.2011, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 2
Всего: 10



несколько способов
1) стандартный способ использования указателей на функции-члены, ну тут в гугл
http://www.gamedev.ru/code/faq/?id=3599
2) в стл
Код

#include <iostream>
#include <functional>
#include <algorithm>

class A{
public:
   A( int a ) : m_a(a) {}
   int getA(){ return m_a; }
private:
   int m_a; 
};

int main()
{
   A a( 10 );
   std::mem_fun_t<int, A> fun = std::mem_fun( &A::getA );
   std::cout << fun( &a ); 
}

3) в новом стандарте использования std::function (аналогично в бусте)
Код

#include <functional>
#include <iostream>

struct X {
      int foo(int a) {return a;}
};

int main()
{
   std::function<int (X*, int)> f;
   f = &X::foo;      // pointer to member

   X x;
   std::cout << f(&x, 5); // call X::foo() for x with 5



Добавлено через 1 минуту и 18 секунд
главное помнить, что указатель на функцию член зависит от двух вещей
1) смещение в классе, те &X::foo
2) адреса самого объекта
PM MAIL   Вверх
bsa
Дата 26.3.2011, 11:15 (ссылка) |  (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(alexvs11 @  26.3.2011,  10:43 Найти цитируемый пост)
главное помнить, что указатель на функцию член зависит от двух вещей
1) смещение в классе, те &X::foo
2) адреса самого объекта 

Да что ты?!?  smile 
Сколько лет знаю С++, но никогда и не догадывался, что размещение подпрограммы в области кода как-то зависит от адреса объекта и количества членов перед ней в определении класса.

Mormishka, тип указателя должен быть int (A::*pFunc)(int). Вызывать нужно так: int r = (a.*pfunc)(x) или int r = (pa->*pfunc)(x), где a - объект типа A, pa - указатель на объект типа A

Это сообщение отредактировал(а) bsa - 27.3.2011, 18:33
PM   Вверх
jonie
Дата 27.3.2011, 12:39 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



bsa, однако чувак говорит не про подпрограмму, а про сам указатель. И да, он хитрее устроен, чем обычный указатель на функцию (подробнее: раз и два)

Это сообщение отредактировал(а) jonie - 27.3.2011, 12:41


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
alexvs11
Дата 27.3.2011, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 2
Всего: 10



Цитата(bsa @  26.3.2011,  11:15 Найти цитируемый пост)
Сколько лет знаю С++, но никогда и не догадывался, что размещение подпрограммы в области кода как-то зависит от адреса объекта и количества членов перед ней в определении класса.

ну да, ну да, ну да, а поля объекта как она получает?
данные объекта функция-член получает через указатель this, который является адресом объекта smile  
PM MAIL   Вверх
mes
Дата 27.3.2011, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(alexvs11 @  26.3.2011,  09:43 Найти цитируемый пост)
смещение в классе, те &X::foo

Код

struct A
{
  int i;
  void f();
};

Код

struct A
{
  void f();
  int i;
};

_обладает_ ли f() в этих примерах разным смещением ?

Добавлено через 2 минуты и 18 секунд
Цитата(alexvs11 @  27.3.2011,  14:36 Найти цитируемый пост)
анные объекта функция-член получает через указатель this

Цитата(alexvs11 @  26.3.2011,  09:43 Найти цитируемый пост)
что указатель на функцию член
1) смещение в классе, те &X::foo
2) адреса самого объекта 

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





--------------------
PM MAIL WWW   Вверх
alexvs11
Дата 27.3.2011, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 2
Всего: 10



Цитата(mes @  27.3.2011,  16:32 Найти цитируемый пост)
_обладает_ ли f() в этих примерах разным смещением ?

не знаю как их можно сравнить, ибо приведение к int не работает и сравнение для разных классов тоже, но

Код

#include <iostream>

struct A
{
  int i;
  int f(){return i;}
  int g(){return 2*i;} 
};

struct B
{
  void f(){}
   int i; 
};

int main()
{
  std::cout << std::boolalpha << ( &A::f == &A::g );
}  

дает false
Цитата(mes @  27.3.2011,  16:32 Найти цитируемый пост)
а указатель на функцию член тоже получает данные через this ?а то из высказываний не совсем понятно, что имеете ввиду...

скажем так, для доступа к функции-члену нужно смещение и адрес объекта, что в этом не есть очевидное?
ну уж то что виртуальная функция зависит от адреса объекта то уж точно сомнений нет?

Добавлено через 12 минут и 5 секунд
вот собсно ответ на вопрос автора

Код

#include <iostream>

class A;
typedef int (A::*pToFunc)(int);

class B
{
public:   
    B(A* a, pToFunc Myfun1)
    {
        m_fun = Myfun1;
        m_pA = a;
         
        std::cout << ( m_pA->*m_fun )( 10 );
    }
private:
    A* m_pA;
    pToFunc m_fun;  
};


class A
{
public:
    B* pB;
    A()
    {
        pB = new B(this, &A::f);
        this->pB=pB;
    }
    int f(int x)
    {
        return x;
    }
    int g(int x)
    {
        return 2*x;
    } 
};

int main()
{
  A a;
}


Это сообщение отредактировал(а) alexvs11 - 27.3.2011, 16:51
PM MAIL   Вверх
mes
Дата 27.3.2011, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(alexvs11 @  27.3.2011,  15:51 Найти цитируемый пост)
скажем так, для доступа к функции-члену нужно смещение и адрес объекта, что в этом не есть очевидное?

1. смещение функции в чем ?
2. для доступа к функции-члену адрес объекта не нужен.. 
а для вызова функции члены только адреса объекта мало, нужен и тип.. 
3. указатель на функцию и имя функции имеют разное поведение ( при вызове)




--------------------
PM MAIL WWW   Вверх
alexvs11
Дата 27.3.2011, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 2
Всего: 10



Цитата(mes @  27.3.2011,  17:19 Найти цитируемый пост)
для доступа к функции-члену адрес объекта не нужен.. а для вызова функции члены только адреса объекта мало, нужен и тип.. 

ну дак ответьте автору без адреса объекта
PM MAIL   Вверх
mes
Дата 27.3.2011, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(alexvs11 @  27.3.2011,  15:51 Найти цитируемый пост)
ну уж то что виртуальная функция зависит от адреса объекта то уж точно сомнений нет

от самого адреса объекта нет smile 
smile


--------------------
PM MAIL WWW   Вверх
alexvs11
Дата 27.3.2011, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 2
Всего: 10



это умная демагогия про то чем отличается функция от ее вызова?
PM MAIL   Вверх
mes
Дата 27.3.2011, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(alexvs11 @  27.3.2011,  16:22 Найти цитируемый пост)
ну дак ответьте автору без адреса объекта 

я пытаюсь заострить Ваше внимание, на не совсем корректном восприятии функции..
по крайней мере такое впечатление сложилось после Ваших высказываний.. 
к посту тс мои замечания фактически не относятся.. 



--------------------
PM MAIL WWW   Вверх
bsa
Дата 27.3.2011, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(jonie @ 27.3.2011,  12:39)
bsa, однако чувак говорит не про подпрограмму, а про сам указатель. И да, он хитрее устроен, чем обычный указатель на функцию (подробнее: раз и два)

Почитал. Узнал много нового. Спасибо.
Знал, что указатель на метод вещь убогая, но даже не представлял, что на столько.
PM   Вверх
alexvs11
Дата 27.3.2011, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 2
Всего: 10



Цитата(bsa @  27.3.2011,  19:18 Найти цитируемый пост)
Знал, что указатель на метод вещь убогая, но даже не представлял, что на столько

поэтому радуемся std::function
PM MAIL   Вверх
mes
Дата 27.3.2011, 19:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(alexvs11 @  27.3.2011,  18:40 Найти цитируемый пост)
поэтому радуемся std::function 

это не пройдет когда нам нужно сделать из метода  с-делегат ( например void(*cb)(void *); )



--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1267 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.