Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Есть ли С++(осоьенно в IAR С++) возможность
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
_Артём_
Есть ли С++(особенно интересует для IAR С++) возможность сделать указатель на метод экземпляра класса?
Ну или способ сделать тоже как-то по другому.

Из EWAVR_CompilerReference.pdf:
Цитата
POINTER TO MEMBER FUNCTIONS
A pointer to a member function can only contain a default function pointer, or a function
pointer that can implicitly be casted to a default function pointer. To use a pointer to a
member function, make sure that all functions that should be pointed to reside in the
default memory or a memory contained in the default memory.
Example
class X
{
public:
__nearfunc void F();
};
void (__nearfunc X::*PMF)(void) = &X::F;


Но пока что-т не получается использовать (или это пример не о том?).
Спасибо.
neiver
Есть и прекрасно работают.
Код
class Foo
{
public:
  void A()
  {
      PORTA = 0;
  }
  void B()
  {
      PORTA = 0xff;
  }
};
// тип указателя на функцию член Foo, возвращающую void и не принимающую аргументов
typedef void (Foo::*FooFuncPtr)();

int main()
{
// экземпляр класса Foo
  Foo foo;
// fPtr указывает на Foo::A
  FooFuncPtr fPtr = Foo::A;
// вызываем Foo::A через указатель для объекта foo
  (foo.*fPtr)();
// fPtr указывает на Foo::B
  fPtr = Foo::B;
// вызываем Foo::B через указатель для объекта foo
  (foo.*fPtr)();
  return 0;
}
dxp
Только следует иметь в виду, что указатели на члены обычно раза в три толще обычных. Толщина зависит от реализации.
_Артём_
Цитата(neiver @ Feb 9 2012, 17:46) *
Код
// fPtr указывает на Foo::A
  FooFuncPtr fPtr = Foo::A;


Наверное, так правильней:
Код
// fPtr указывает на Foo::A
  FooFuncPtr fPtr = &Foo::A;


Цитата(dxp @ Feb 10 2012, 05:29) *
Только следует иметь в виду, что указатели на члены обычно раза в три толще обычных. Толщина зависит от реализации.


Ну если сам метод толстый, то толщиной указателей можно пренебречь.
_Артём_
C указателями на методы боль-менее ясно, но вот хочется странного...
Можно ли такое:

Код
class A {
public:
    void f(unsigned char b) {
        // какие-то действия
    }
};
class B {
public:
    void f(unsigned char b) {
        // какие-то действия
    }
};

int main( void )
{
    A a;
    B b;
    // FuncPtr - такой указатель чтоб на любой метод (с учётом сигнатуры конечно)
    // конкретного экземпляра указывал
    FuncPtr f_ptr;
    f_ptr=&a.f();
    f_ptr();// вызов a.f

    f_ptr=&a.f();
    f_ptr();// вызов b.f

}
dxp
QUOTE (_Артём_ @ Feb 10 2012, 22:41) *
C указателями на методы боль-менее ясно, но вот хочется странного...

Виртуальными функциями пахнет. Попробовать создать для обоих классов предка, где объявить виртуальную функцию f(), перекрываемую в наследниках. На неё и заводить указатель. Нет уверенности, что это прокатит с указателями на функции. Надо плотно фтыкать стандарт или пробовать.

Вообще, указателями на члены без настоятельной необходимости пользоваться, имхо, не следует. Эффективности кода они не дают, удобство использования тоже сомнительно.
_Артём_
Цитата(dxp @ Feb 10 2012, 19:11) *
Виртуальными функциями пахнет. Попробовать создать для обоих классов предка, где объявить виртуальную функцию f(), перекрываемую в наследниках.

Похоже на то...

Цитата(dxp @ Feb 10 2012, 19:11) *
Нет уверенности, что это прокатит с указателями на функции. Надо плотно фтыкать стандарт или пробовать.

Так всё сложно и непонятно?

Цитата(dxp @ Feb 10 2012, 19:11) *
Надо плотно фтыкать стандарт или пробовать.

Лучше пробовать...

Цитата(dxp @ Feb 10 2012, 19:11) *
Вообще, указателями на члены без настоятельной необходимости пользоваться, имхо, не следует. Эффективности кода они не дают, удобство использования тоже сомнительно.

Похоже действительно: хочется странного.
neiver
Цитата(_Артём_ @ Feb 10 2012, 19:41) *
C указателями на методы боль-менее ясно, но вот хочется странного...

То, что вы хотите называется делегат.
В сети довольно много реализаций делегатов на С++, например:
http://www.rsdn.ru/article/cpp/fastdelegate.xml
http://www.codeproject.com/Articles/11015/...ast-C-Delegates
http://www.rsdn.ru/article/cpp/delegates.xml
Первое, что нагуглилось.
_Артём_
Цитата(neiver @ Feb 10 2012, 19:47) *
То, что вы хотите называется делегат.

Точно, вспомнил...
Когда с C# разбирался прочитал про них и благополучно забыл.

Цитата(neiver @ Feb 10 2012, 19:47) *
В сети довольно много реализаций делегатов на С++, например:

Будем посмотреть...есть ли от них прок и сколько стоит их использование.


neiver
Я немного поэкспериментировал с делегатами по этой методике. В предельно сжатом виде получается что-то такое:
Код
struct GenericClass{};
typedef void (GenericClass::*VoidFuncPtr)();

class delegate{
public:
  template<class ObjT>
  explicit delegate(ObjT *obj, void (ObjT::*func)() )
  {
    _func = reinterpret_cast<VoidFuncPtr>(func);
    _pThis = reinterpret_cast<GenericClass*>(obj);
  }
  void operator ()(){
     (_pThis->*_func)();
  }
private:
  VoidFuncPtr _func;
  GenericClass *_pThis;
};

class Foo{
public:
  void Func(){
    PORTA = 0xff;
  }
};

int main()
{
  Foo foo;
  delegate d(&foo, &Foo::Func);
  d();
  return 0;}

Получается около 40-50 тактов на вызов такого делегата под IAR for AVR. Многовато. Это в 3-4 раза больше чем вызов обычной виртуальной функции. В прерываниях такое лучше не использовать.
_Артём_
Спасибо за ссылки и пример, думаю надолго разбираться хватит.

Цитата(neiver @ Feb 11 2012, 16:33) *
Получается около 40-50 тактов на вызов такого делегата под IAR for AVR. Многовато. Это в 3-4 раза больше чем вызов обычной виртуальной функции. В прерываниях такое лучше не использовать.


Смотря какое прерывание:
Код
#pragma vector=TIMER1_COMPA_vect
__interrupt void ISR_10_Hz()
{
// какие-то действия
}

если прерывание возникает с частотой десятки-сотни герц, то 40-50 тактов - сущий пустяки.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.