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


Автор: Royan 3.9.2004, 12:44
Вопрос довольно хитрый и содержит тьму подводных камней:

Есть класс и его потомок:
Цитата
class Window : public /*some base "Frame" class*/{
 
//...
 
typedef int (Window::*MsgHandler)(WPARAM,LPARAM);
  std::map<
int, MsgHandler> MsgMap;
 
//...
}

class ChildWnd : public Window{

}


Как мне избежать инстанциирования объекта MsgMap в родительском классе, если я создаю экземпляр класса потомка, по возможности избегая лишних строк кода. В идеале я бы хотел это сделать во время компиляции.

Автор: Royan 3.9.2004, 20:21
Поступила мысль сделать этот член статическим, но это не убирает главной проблемы, так как классы будут все равно созданы от корня => отработают деструкторы по умолчанию => инстанциируются не нужные обработчики сообщений, а именно этого я и хочу избежать.

Конечно можно было бы в каждом конструкторе бервым делом чистить содержание карты но это расточительно с точки зрения быстродействия

Автор: AndyY 3.9.2004, 23:08
Royan
Я правильно понял, что хочется иметь один экземпляр MAP на каждый класс (что-то типа VTBL, к примеру, VTBL)
думаю, что хорошо эта проблема средствами C++ не решается.
Статический map будет один на всю программу - соответственно, одной карты сообщений на всех мало. Можно подумать относительно глобальной карты где ключем будет: (const char* +message), const char * - указатель на название класса окна, можно получить через RTTI - но это тоже плохо катит в случае наследования.

btw, зачем такой код нужен вообще? Один фиг для каждого класса окна нужно будет вызывать функцию, которая добавляет обработчики сообщений в карту (что-то врода AddMessageHandler(WM_PAINT, OnPaint);...). Соответственно, кода становится ничуть не больше, если использовать виртуальную функцию обработки сообщений, устроенную примерно так

if( msg == WM_PAINT )return OnPaint();
else if( msg == WM_LBUTTONDOWN )return OnLButtonDown(HIWORD(l), LOWORD(l));
else ...

короче, как сделано в ATL

кроме наглядности, такой подход имеет ряд преимуществ - можно при вызове функций передавать не абстрактные WPARAM, LPARAM, а раскрытые данные сообщения.

Кода не больше, а очевидность выше и не нужна карта - что еще нужно.
Выигрыш по производительности поиска от использования map для реализации карты сообщений минимальна, особо если часто используемые сообщения вытащить "наверх" в первые сравнения.

Автор: Sceptik 30.8.2006, 11:37
class Window{
... 
virtual const std::map<int, MsgHandler> &getMsgMap()
{
     static std::map<int, MsgHandler> msgMap;
     return msgMap;
}

};

Автор: Earnest 30.8.2006, 11:56
Sceptik, надо полагать и Royan и Gaz за прошедшие годы как-то решили свои проблемы...
 smile  smile  smile  

Автор: Sceptik 30.8.2006, 11:58
Earnest, smile я просто не посмотрел=)... на года. Внизу ссыллки я и шелкнул=)

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