Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Вопрос про применение Typedef для функций


Автор: Robix 28.5.2015, 16:03
Здравстуйте, есть такой код

Order.h
...
typedef void __stdcall ORDER_CALLBACK( PORDERHDR porder, int extra_data );
typedef                ORDER_CALLBACK  *PORDER_CALLBACK;
...

Order.cpp
...
#include "Order.h"
...
ORDER_CALLBACK orderCallback;
...

Можете объяснить, что означает 
typedef void __stdcall ORDER_CALLBACK( PORDERHDR porder, int extra_data );
Что в данном случае есть ORDER_CALLBACK ? 

И далее в Order.cpp
ORDER_CALLBACK orderCallback;
orderCallback это будет функция или что-то еще? Как это понимать?




Автор: baldina 28.5.2015, 22:14
функция. такой typedef дает возможность сделать краткую декларацию, например
Код

class A {
  typedef void F ();
  virtual F f1 = 0;
  F f2;
};

void A::f2() {}
см. http://ideone.com/7fUoOP

Автор: borisbn 29.5.2015, 13:03
Есть такой тип в Си - указатель на функцию. Чаще всего его используют, чтобы передать в какую-то чужую функцию свою функцию, которую чужая будет вызывать (т.н. callback'и). Например, некая сетевая библиотека умеет передавать и принимать по сети данные, но что при получении данных с ними делать она не знает, и, поэтому, она требует, чтобы тот, кто ею пользуется, указал свою функцию, которую сетевая библиотека будет вызывать при приёме данных.
Код
class NetLib {
...
   void setCallBackOnDataReceived( void (*callback)( void * data, int dataSize ) ) {
        onDataReceived = callback;
   }

   void receiveData() {
         void * data = ...;
         int dataSize = ...;
        onDataReceived( data, dataSize );
   }
private:
   void (*onDataReceived)( void * data, int dataSize );
};

Как видишь, определение переменной onDataReceived и сигнатура функции setCallBackOnDataReceived довольно громоздкие, и при изменении количества или типов параметров в callback'е придётся менять в нескольких местах. Чтобы этого избежать мы можем ввести typedef для типа "указатель на функцию, принимающую void * и int и возвращающую void". На Си это будет выглядеть так:
Код
typedef void (*onDataReceived_t)( void * data, int dataSize );

и код в примере выше будет выглядеть почище:
Код
class NetLib {
...
   typedef void (*onDataReceived_t)( void * data, int dataSize );
   void setCallBackOnDataReceived( onDataReceived_t callback ) {
        onDataReceived = callback;
   }

   void receiveData() {
         void * data = ...;
         int dataSize = ...;
         onDataReceived( data, dataSize );
   }
private:
   onDataReceived_t onDataReceived;
};

Теперь при изменении параметров callback'а нужно будет только поправить определение типа onDataReceived_t и, собственно, вызов самого callback'а.

Добавлено через 6 минут и 40 секунд
Цитата(Robix @  28.5.2015,  16:03 Найти цитируемый пост)
Что в данном случае есть ORDER_CALLBACK ? 

ORDER_CALLBACK - это тип, в экземпляре которого может храниться указатель на функцию, принимающую два параметра, ничего возвращающую и имеющую тип вызова __stdcall.
Цитата(Robix @  28.5.2015,  16:03 Найти цитируемый пост)
orderCallback это будет функция или что-то еще?

orderCallback - это экземпляр типа ORDER_CALLBACK. Пока он не проинициализирован каким-то указателем на функцию, использовать его нельзя (так же, как и с обычными указателями).

Автор: baldina 29.5.2015, 14:55
замечаете разницу?
Код

typedef void (*onDataReceived_t)( void * data, int dataSize );
// vs
typedef void (  onDataReceived_t)( void * data, int dataSize );


так что
Цитата(borisbn @  29.5.2015,  13:03 Найти цитируемый пост)
ORDER_CALLBACK - это тип, в экземпляре которого может храниться указатель на функцию
...
orderCallback - это экземпляр типа ORDER_CALLBACK. Пока он не проинициализирован каким-то указателем на функцию...

http://ideone.com/N0ehAL

потому что 
Цитата

A typedef of function type may be used to declare a function but 
shall not be used to define a function (8.4).
[Example:
typedef void F();
F fv; // OK: equivalent to void fv();
F fv { } // illformed
void fv() { } // OK: definition of fv
end example]


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)