gui_moderator (gui_moderator) wrote in gui_programming,
gui_moderator
gui_moderator
gui_programming

C++ Tricks: Функция в функции

Никогда не жалел о том, что в свое время перешел с Паскаля на С++. Лишь двух вещей мне нехватало в С++: оператора with .. do и возможности определять локальные функции. К первому я привык, а вторую проблему оказалось возможным элегантно решить с помощю unnamed-структур.

Рассмотрим следующую задачу: у нас есть окна, с которыми связаны массивы данных. В одной из функци нашей необъятной программы мы должны в нескольких местах проверять наличие этих данных и освобождать занимаемую ими память. Вот так:
LPBYTE pData = (LPBYTE)GetWindowLongPtr(hWnd, GWL_USERDATA);
if(pData)
{
    delete [] pData;
    SetWindowLongPtr(hWnd, GWL_USERDATA, NULL);
}
Не хочется в двух или более местах писать один и тот же код. Самое очевидное решение - определить вспомогательную функцию, с помощью которой и выполнять эти нехитрые манипуляции. Действительно, можно использовать anonymous namespace и спрятать нашу функцию от внешнего мира подобным образом. Можно объявить эту функцию как private static член класса и остаться довольным. Однако, оба эти способа все же делают нашу вспомогательную функцию доступной не только вызывающей ее функции. Лучше поступить следующим образом:
void foo()
{
   struct
   {
      void operator()(HWND hWnd)
      {
	 LPBYTE pData = (LPBYTE)GetWindowLongPtr(hWnd, GWL_USERDATA);
	 if(pData)
	 {
	    delete [] pData;
	    SetWindowLongPtr(hWnd, GWL_USERDATA, NULL);
	 }
      }
    } 
    function;

    .....
    .....
    function(hWnd1);
    .....
    function(hWnd2)
    .....
    function(hWnd3);
    .....
    .....
}
Заметьте, структура не имеет имени и единственный объект этого неименнованного типа используется как функция. Получилась локальная функция, которой иногда так нехватает!

П.С. Строка (LPBYTE)GetWindowLongPtr(hWnd, GWL_USERDATA); генерирует warning C4312. О том как элегантно избавться от него, я расскажу в одном из следующих постов.
Tags: c++
  • Post a new comment

    Error

    default userpic
  • 8 comments