реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Есть ли С++(осоьенно в IAR С++) возможность
_Артём_
сообщение Feb 9 2012, 13:36
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Есть ли С++(особенно интересует для 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;


Но пока что-т не получается использовать (или это пример не о том?).
Спасибо.
Go to the top of the page
 
+Quote Post
neiver
сообщение Feb 9 2012, 15:46
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Есть и прекрасно работают.
Код
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;
}
Go to the top of the page
 
+Quote Post
dxp
сообщение Feb 10 2012, 03:29
Сообщение #3


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Только следует иметь в виду, что указатели на члены обычно раза в три толще обычных. Толщина зависит от реализации.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 10 2012, 12:51
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(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) *
Только следует иметь в виду, что указатели на члены обычно раза в три толще обычных. Толщина зависит от реализации.


Ну если сам метод толстый, то толщиной указателей можно пренебречь.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 10 2012, 15:41
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



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

}
Go to the top of the page
 
+Quote Post
dxp
сообщение Feb 10 2012, 17:11
Сообщение #6


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



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

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

Вообще, указателями на члены без настоятельной необходимости пользоваться, имхо, не следует. Эффективности кода они не дают, удобство использования тоже сомнительно.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 10 2012, 17:41
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(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) *
Вообще, указателями на члены без настоятельной необходимости пользоваться, имхо, не следует. Эффективности кода они не дают, удобство использования тоже сомнительно.

Похоже действительно: хочется странного.
Go to the top of the page
 
+Quote Post
neiver
сообщение Feb 10 2012, 17:47
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Цитата(_Артём_ @ 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
Первое, что нагуглилось.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 10 2012, 21:15
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(neiver @ Feb 10 2012, 19:47) *
То, что вы хотите называется делегат.

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

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

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


Go to the top of the page
 
+Quote Post
neiver
сообщение Feb 11 2012, 13:33
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Я немного поэкспериментировал с делегатами по этой методике. В предельно сжатом виде получается что-то такое:
Код
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 раза больше чем вызов обычной виртуальной функции. В прерываниях такое лучше не использовать.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 12 2012, 20:52
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Спасибо за ссылки и пример, думаю надолго разбираться хватит.

Цитата(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 тактов - сущий пустяки.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 17th June 2025 - 04:54
Рейтинг@Mail.ru


Страница сгенерированна за 0.01468 секунд с 7
ELECTRONIX ©2004-2016