Указатели нулевой функции в новом объекте на самом деле не являются nullptr

Я использую C ++ (11) с Visual Studio 2012.

Я создаю окна, используя пользовательский класс-оболочку.

CUIWindow* winA = new CUIWindow ( NULL, TEXT("winAClassName"), TEXT("winACaption"), 200, 300 );

Каждое окно имеет серию «сокетов» для событий pluggabe.

public:
LPFNCUIWINDOWONCLOSE OnClose;
LPFNCUIWINDOWONDESTROY OnDestroy;
LPFNCUIWINDOWONNOTIFY OnNotify;
LPFNCUIWINDOWONSIZE OnSize;
LPFNCUIWINDOWONHOTKEY OnHotkey;

Я использую следующий макрос для вызова различных сокетов, которые могут быть назначены моему классу окна в цикле сообщений:

#define MapEvent(e, fn) \
{ \
case e: \
if ( fn != nullptr ) \
return static_cast<LPARAM>( HANDLE_##e((hWnd), (wParam), (lParam), fn) ); \
}

У меня есть ситуация, как показано ниже;

Код с точкой останова

Вы можете предположить, что pWindow является действительным указателем на объект CUIWindow.

На показанной точке останова некоторые неинициализированные события OnXXXX определены как 0xCDCDCDCD и вызываются, когда приходит их сообщение (независимо от того, что я никогда не устанавливал их явно после создания класса). Это дает мне исключение 0x0BADFOOD, потому что указатель на функцию плохой. Я бы предположил, что нулевые указатели на функции были бы пойманы if ( fn != nullptr ) однако сейчас я не так уверен и прошу помощи;

  1. Объясните, почему это происходит
  2. Найдите лучший способ предотвратить возникновение этого, предпочтительно без явной установки нулевых указателей всех функций в конструкторе, поскольку иногда имеется множество сокетов.

0

Решение

Неинициализированные указатели обычно не устанавливаются в нулевой указатель автоматически. Есть ли возможность немного изменить свой класс? Если это так, вы можете установить их все, не называя их всех.

struct CUIWindowEvents
{
LPFNCUIWINDOWONCLOSE OnClose;
LPFNCUIWINDOWONDESTROY OnDestroy;
LPFNCUIWINDOWONNOTIFY OnNotify;
LPFNCUIWINDOWONSIZE OnSize;
LPFNCUIWINDOWONHOTKEY OnHotkey;
}

class CUIWindow
{
public:
CUIWindowEvents Events; // move all events to a simple struct

CUIWindow() // and in your constructor
: Events() // initialise Events; this sets all the pointers to null
{ ... }
};
1

Другие решения

В конструкторе для CUIWindow класс, вам нужно явно установить эти члены nullptr (или же NULL или же 0); поскольку все эти указатели являются необработанными указателями, они не будут автоматически установлены в 0 в CUIWindow конструктор:

CUIWindow ( /* whatever parameters... */)
: OnClose(nullptr)
, OnDestroy(nullptr)
, OnNotify(nullptr)
, OnSize(nullptr)
, OnHotkey(nullptr)
{
// the constructor logic...
}
2

По вопросам рекламы [email protected]