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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Присвоение указателей функций 
:(
    Опции темы
Vovkin
Дата 10.10.2008, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Помогите зазобраться ка сделать.
Есть некоторый класс описанный в виде
Код

typedef void (A::*pMyFuncType)(int, int)
class A
{
  ...
  pMyFuncType Func;
}

В общем в классе есть указатель на функцию,
которая дергается, если в классе происходят какие либо
действия.
Есть второй класс
Код

class B
{
  ...
  A *MyA;
  void MyFunc(int, int);
}

В общем класс, в котором есть объекс класса А
и некоторая функция.
Вопрос. Как мне для объекта MyA присвоить
его указателю Func указательфункции MyFunc изкласса B.
 Т.е. провернуть нечто следующее
Код

  MyA->Func = MyFunc;

Весь смысл в том, что мне нужно дергать метод класса,
который не является потомком другого класса.
(В данном примере В не потомок А.) А просто
в этом классе есть объект другого класса.
Компилятор настойчиво просит писать так
Код

  MyA->Func = &B::MyFunc;

При этом все компилируется, но работает неправильно.
Т.к. присваивается не указатель моего созданного класса В,
а создется где-то внутри пустой класс В и дергается его
метод MyFunc.
Вот и спрашиваю как мне праивльно сделать?
Да у меня Visual Studio 2008.
PM MAIL   Вверх
bsa
Дата 10.10.2008, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Почитай про boost::function - найдешь решение  smile 
PM   Вверх
J0ker
Дата 10.10.2008, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Vovkin @  10.10.2008,  23:28 Найти цитируемый пост)
Компилятор настойчиво просит писать так
Код

  MyA->Func = &B::MyFunc;


я вам не верю
компилятор это не скомпилирует, т.к. MyA->Func и &B::MyFunc - имеют разные типы, которые не конвертируются имплиситли.
это будет работать только так
Код

  MyA->Func = reinterpret_cast<pMyFuncType>(&B::MyFunc);


Цитата(Vovkin @  10.10.2008,  23:28 Найти цитируемый пост)
Т.к. присваивается не указатель моего созданного класса В,
а создется где-то внутри пустой класс В и дергается его
метод MyFunc.

во-первых, ваше понимание механизма в корне не правильно
во-вторых такое использование функций-мемберов грозит тяжелыми осложнениями с возможным летальным исходом
вообще надо взять за правило, что всякое явное преобразование типов (за некоторым исключением dynamic_cast'ов) - указывает на неправильный дизайн.

Это сообщение отредактировал(а) J0ker - 13.10.2008, 23:33


--------------------
user posted image
PM MAIL   Вверх
UnrealMan
Дата 11.10.2008, 02:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(J0ker @  11.10.2008,  00:59 Найти цитируемый пост)
вообще надо взять за правило, что всякое явное преобразование типов (за некоторым исключением dynamic_cast'ов) - указывает на неправильный дизайн. 

Хреновое правило smile 
PM MAIL   Вверх
J0ker
Дата 13.10.2008, 04:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(UnrealMan @ 11.10.2008,  02:30)
Цитата(J0ker @  11.10.2008,  00:59 Найти цитируемый пост)
вообще надо взять за правило, что всякое явное преобразование типов (за некоторым исключением dynamic_cast'ов) - указывает на неправильный дизайн. 

Хреновое правило smile

почему?


--------------------
user posted image
PM MAIL   Вверх
Lazin
Дата 13.10.2008, 05:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



потому-что явное лучше неявного smile 
PM MAIL Skype GTalk   Вверх
Vovkin
Дата 13.10.2008, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(J0ker @ 10.10.2008,  23:59)

  MyA->Func = reinterpret_cast<pMyFuncType>(&B::MyFunc);

Ну да. Именно так. Я просто опустил часть записи.
Собственно я уже сделал по простоту с использованием
статических методов и передачей среди параметров
указателя на объект. Просто и без заморочек.
Все заработало как надо.
PM MAIL   Вверх
mes
Дата 13.10.2008, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



a почему не сделать  примерно так? :
Код


class A 
{
   protected:
      virtual void MyFuncCallback (int, int) =0;
};
class B
{
   protected:
    class myA : public A
   {
       public:
          myA (B * obj) : p_obj (obj) {}
       protected:
           virtual void MyFuncCallback (int a, int b)  { p_obj->MyFunc(a,b); }
      private:
          B p_obj;            
   };
    void MyFunc (int a, int b)  { ... }

   private:
        myA  m_a;

   public:
         B() : m_a(this){}
   
};




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


Опытный
**


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

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



Цитата(Lazin @  13.10.2008,  05:29 Найти цитируемый пост)
потому-что явное лучше неявного

это неправильный аргумент
в подавляющем большинстве случаев (как в вышеуказанном) компилятор не пропустит преобразование типов, которое может привести к нежелательным последствиям



--------------------
user posted image
PM MAIL   Вверх
UnrealMan
Дата 13.10.2008, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(J0ker @  13.10.2008,  05:15 Найти цитируемый пост)
почему?

Наверное, потому, что альтернативой такому "неправильному дизайну" будет более громоздкий и менее удобочитаемый код. Например, все временные объекты, создаваемые выражениями вида T(expression-list), придётся делать именованными переменными (ну и зачем это нужно?).
PM MAIL   Вверх
J0ker
Дата 13.10.2008, 23:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(UnrealMan @ 13.10.2008,  22:53)
Цитата(J0ker @  13.10.2008,  05:15 Найти цитируемый пост)
почему?

Наверное, потому, что альтернативой такому "неправильному дизайну" будет более громоздкий и менее удобочитаемый код. Например, все временные объекты, создаваемые выражениями вида T(expression-list), придётся делать именованными переменными (ну и зачем это нужно?).

почему все??? при наличии имплисит преобразования все пройдет нормально. При отсутствии оного - вместо тупого каста надо подумать что тут что-то не так. Безусловно бывают исключения (например ambiguous), но в C++ их все-таки постарались свести к минимуму, и на возмущения компилятора лучше обратить более пристальное внимание...

Это сообщение отредактировал(а) J0ker - 13.10.2008, 23:03


--------------------
user posted image
PM MAIL   Вверх
UnrealMan
Дата 13.10.2008, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(J0ker @  14.10.2008,  00:01 Найти цитируемый пост)
при наличии имплисит преобразования все пройдет нормально

Какого ещё implicit преобразования? smile Вот тебе пример кода.

Код

foo(char ch)
{
     bar(std::string("string literal") + ch);
}

Где ты тут implicit преобразование применишь?
PM MAIL   Вверх
J0ker
Дата 13.10.2008, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(UnrealMan @  13.10.2008,  23:08 Найти цитируемый пост)

Код

foo(char ch)
{
     bar(std::string("string literal") + ch);
}

Где ты тут implicit преобразование применишь? 

ну не будьте занудой  smile
вы отлично понимаете о чем я говорю
приведенный вами пример - особый случай особо оговоренный стандартом - данное преобразование эквивалентно конструированию временного объекта - так-же как и имплисит преобразование.


--------------------
user posted image
PM MAIL   Вверх
UnrealMan
Дата 13.10.2008, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Кстати, раз уж в другой теме мы про исключения заговорили... Когда мы пишем

Код

throw Type(EXPRESSION_LIST);

мы тоже юзаем преобразовани типа. Тут тоже неправильный дизайн?

Это сообщение отредактировал(а) UnrealMan - 13.10.2008, 23:27
PM MAIL   Вверх
J0ker
Дата 13.10.2008, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(UnrealMan @  13.10.2008,  23:27 Найти цитируемый пост)
мы тоже юзаем преобразовани типа. Тут тоже неправильный дизайн?

см.выше


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

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

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

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

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


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

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


 




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


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

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