Вопрос по классам знатокам С++

Тема в разделе "LANGS.C", создана пользователем Magnum, 14 ноя 2011.

  1. Magnum

    Magnum New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    925
    Привет
    Есть 3 структуры (основные) и одна базовая.

    Код (Text):
    1. typedef struct _TBASE
    2. {
    3.  unsigned _int64 qFlags;
    4.  bool blEnabled;
    5. } TBASE, *PTBASE;
    Код (Text):
    1. typedef struct _T1: public TBASE
    2. {
    3.  int a;
    4.  int b;
    5.  char x;
    6.  char y;
    7. };
    Код (Text):
    1. typedef struct _T2: public TBASE
    2. {
    3.  short b;
    4.  short a;
    5.  char x;
    6.  char y;
    7. };
    Код (Text):
    1. typedef struct _T3: public TBASE
    2. {
    3.  int b;
    4.  short a;
    5.  char y;
    6.  char x;
    7. };
    3 структуры полностью идентичны. Имена элементов одни и те же. Разница между ними лишь в порядке элементов и в их размере. Количество элементов в структуре в действительности больше, чем я привел в примере. Реальное количество элементов около 200. Но принцип все тот же. Имена элементов во всех структурах совпадает.

    Тип структуры зависит от элемента qFlags, который ВСЕГДА идет первым и который явно говорит, что за структура в файле.


    Мне нужно в своем коде получать и перезаписвывать некоторые элементы.
    И каждый раз делать switch/case мне не удобно.
    Хочется написать обработчик, который сам определит нужный тип структуры и запишет нужный элемент. Делать 200 геттеров/сеттеров тоже не хотелось бы. 200 свитч/кейзов в обработчике тоже не хочу. Есть ли какой-то простой способ, который позволил бы в зависимости от ситуации обращаться к нужной структуре?
     
  2. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    могу предложить так

    Код (Text):
    1. struct C1
    2. {
    3.     int a;
    4.     char b;
    5. };
    6.  
    7. struct C2
    8. {
    9.     int b;
    10.     char a;
    11. };
    12.  
    13. #define DECLARE_GET(name)  \
    14.     template <typename T, typename V>   \
    15.     void get_##name(T &t, V &val)   \
    16.     {   \
    17.         val = t.name;   \
    18.     }
    19.  
    20. DECLARE_GET(a);
    21. DECLARE_GET(b);
    22.  
    23. int _tmain(int argc, _TCHAR* argv[])
    24. {
    25.     C1 c1;
    26.     int x;
    27.     get_a(c1, x);
    28.     get_b(c1, x);
    29.     C2 c2;
    30.     int y;
    31.     get_a(c2, y);
    32.  
    33.     return 0;
    34. }
    геттеры придётся всё-же объявлять
     
  3. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Как правило это признак плохого. Если бы вы объяснили, что вы хотите сделать... Сомнительно, что можно однотипно работать с таким набором.
     
  4. xh4ck

    xh4ck New Member

    Публикаций:
    0
    Регистрация:
    6 мар 2005
    Сообщения:
    60
    Адрес:
    Russia
    Не совсем понятно как вы именно вы собираетесь "получать и перезаписывать некоторые элементы" чем-то универсальным, т.к. размер элементов у вас для каждого типа разный: что вы будете получать с поля "х" int или short, в зависимости от этого может и логика разной быть. Соответственно, должен быть написан отдельный код для каждой из 3х структур. Используйте паттерн "Factory" и реализуйте логику для каждой из структур, там где логика обработки идентична (совпадает размер данных, например) - выносите в общий интерфейс базового класса.
     
  5. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    вероятнее всего это legacy code
     
  6. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Magnum
    Код (Text):
    1. Вопрос по классам знатокам С++
    С таким заголовком в конце сообщения должна быть фраза: "А теперь, уважаемые знатоки, внимание вопрос!".

    А вообще гамнакот конечно жжот. Одна только стилистика объявления структуры чего стоит. Собственно, в чем вопрос-то? Зачем с таким кодом какие-то там геттеры? Почему просто не писать напрямую в поля по их именам?
     
  7. Magnum

    Magnum New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    925
    Классический пример:
    Есть OPTIONAL_IMAGE_HEADER32 и OPTIONAL_IMAGE_HEADER64
    Нужно к примеру перезаписать размер хипа.

    Мой пример:
    Есть файл, в нем заголовок. Три типа заголовка. В зависимости от типа файла.
    Мне нужно считать/переписать некоторые поля в заголовке.

    Т.е. сами структуры уже даны и переписывать я их не смогу. Но под каждую структуру дублировать код тоже не хочется, потому что структуры фактически идентичны.
     
  8. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Magnum
    Шаблонная функция?
     
  9. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    шаблонную функцию обработки (изменения полей)

    Код (Text):
    1. template< typename T >
    2. SetFields(T& header)
    3. {
    4.     header->field=somevalue;
    5.  
    6. }
    Вот и не надо
    ммм??
     
  10. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
  11. Magnum

    Magnum New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    925
    punxer
    Мне неловко за глупые вопросы. Но я кодю на чистом С и С++ для меня в новинку.
    Можно простой конкретный пример, как для IMAGE_OPTIONAL_HEADER32 и IMAGE_OPTIONAL_HEADER64 сделать шаблонную функцию для изменения в них полей.
    Например размера стека или хипа.
    И как ее вызывать. :)
     
  12. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    Код (Text):
    1. template <typename TImageOptionalHeader>
    2. inline void SetSizeOfStackReserve(TImageOptionalHeader &header, DWORD dwValue)
    3. {
    4.    header.SizeOfStackReserve = dwValue;
    5. }
    6.  
    7. int main()
    8. {
    9.    IMAGE_OPTIONAL_HEADER h32;
    10.    SetSizeOfStackReserve(h32, 0x1000000);
    11.  
    12.    IMAGE_OPTIONAL_HEADER64 h64;
    13.    SetSizeOfStackReserve(h64, 0x1000000);
    14. }