reinterpret_cast - bad design?
От: Sir Wiz Россия  
Дата: 12.10.04 13:05
Оценка:
Добрый день!

Имеется класс с его закрытыми членами:

class Object
{
protected:
    int    m_i;
    char * m_p;
....
};

Трогать класс нельзя. Методов, возвращающих В некоторый момент понадобилось обратиться к членам этого класса. Например для сериализации. Сохранить текущее состаяние экземпляра. (Напрямую копировать память, занимаемую экземпляром естественно нельзя, сущность на которую указывает m_p тоже нужно сохранить). Предлагается такое решение:

class SObject : public Object
{
public:
  void Dump(FILE * stream)
    {
        fwrite(&m_i, sizeof(int), 1, stream);
        fwrite(m_p, strlen(m_p) + 1, 1, stream);
    }
};

// Далее где-то в коде:

Object * obj;
FILE * stream;
....
reintrpret_cast<SObject *>(obj)->Dump(stream);


SObject не имеет (не добавляет) виртуальных функций, всё работает отлично.

Но настораживает кастинг вниз. Должно быть это есть признак bad dasign класса Object, но ничего с ним уже не поделаешь. Можно ли найти более элегантный способ решения проблемы?
... << RSDN@Home 1.1.4 @@subversion >>
Re: reinterpret_cast - bad design?
От: sadomovalex Россия http://sadomovalex.blogspot.com
Дата: 12.10.04 13:39
Оценка:
Здравствуйте, Sir Wiz, Вы писали:

SW>Добрый день!


[skipped]

SW>Но настораживает кастинг вниз. Должно быть это есть признак bad dasign класса Object, но ничего с ним уже не поделаешь. Можно ли найти более элегантный способ решения проблемы?


Можно попробовать так сделать:
class Object
{
protected:
    int    m_i;
    char * m_p;
};

class ObjectDumper
{
public:
    void Dump(FILE* stream, Object* a)
    {
        class Friend: public Object { friend ObjectDumper; };
        
        fwrite(&((Friend*)a)->m_i, sizeof(int), 1, stream);
        fwrite(((Friend*)a)->m_p, strlen(((Friend*)a)->m_p) + 1, 1, stream);
    }
};


Object a;
ObjectDumper b;

FILE *stream;
b.Dump(stream, &a);


За подробностями сюда
Автор: _defrager
Дата: 21.09.04
"Что не завершено, не сделано вовсе" Гаусс
Re: reinterpret_cast - bad design?
От: Аноним  
Дата: 12.10.04 13:44
Оценка:
Здравствуйте, Sir Wiz, Вы писали:

SW>Добрый день!


SW>Имеется класс с его закрытыми членами:


SW>
SW>class Object
SW>{
SW>protected:
SW>    int    m_i;
SW>    char * m_p;
SW>....
SW>};
SW>

SW>Трогать класс нельзя. Методов, возвращающих В некоторый момент понадобилось обратиться к членам этого класса. Например для сериализации. Сохранить текущее состаяние экземпляра. (Напрямую копировать память, занимаемую экземпляром естественно нельзя, сущность на которую указывает m_p тоже нужно сохранить). Предлагается такое решение:

SW>
SW>class SObject : public Object
SW>{
SW>public:
SW>  void Dump(FILE * stream)
SW>    {
SW>        fwrite(&m_i, sizeof(int), 1, stream);
SW>        fwrite(m_p, strlen(m_p) + 1, 1, stream);
SW>    }
SW>};

SW>// Далее где-то в коде:

SW>Object * obj;
SW>FILE * stream;
SW>....
SW>reintrpret_cast<SObject *>(obj)->Dump(stream);
SW>


SW>SObject не имеет (не добавляет) виртуальных функций, всё работает отлично.


SW>Но настораживает кастинг вниз. Должно быть это есть признак bad dasign класса Object, но ничего с ним уже не поделаешь. Можно ли найти более элегантный способ решения проблемы?



По сути все сделано нормально, и не надо мудрить. Однако если все же кастинг настораживает есть более элегантный способ. Можно попробовать так

class SObject : public Object
{
public:
  SObject(const Object &obj) { m_i = obj.m_i; m_p = obj.m_p; }

  void Dump(FILE * stream)  { ...}
};

// Далее где-то в коде:

Object * obj;
FILE * stream;

SObject s_obj(*obj);  // ну разумеется здесь имеется ввиду валидный указатель на нормальный объект
s_obj->Dump(stream);


по сути тоже самое, но вроде как изящнее.
С уважением, Алексей.
Re[2]: reinterpret_cast - bad design?
От: Аноним  
Дата: 12.10.04 13:50
Оценка:
Сори, ошибочка. конечно же следует читать как
 ...

Object * obj;
FILE * stream;

SObject s_obj(*obj);
s_obj.Dump(stream);


С уважением, Алексей.
Re[2]: reinterpret_cast - bad design?
От: Sir Wiz Россия  
Дата: 14.10.04 06:05
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>по сути тоже самое, но вроде как изящнее.


Да, спасибо. идея мне нравится.

Только, к сожалению в существующем проекте так сделать не получится — не смогу я объяснить заказчику, почему из-за моих эстетических потребностей отлично работающий модуль станет работать медленнее
... << RSDN@Home 1.1.4 @@subversion >>
Re[3]: reinterpret_cast - bad design?
От: Lapulya  
Дата: 14.10.04 11:57
Оценка:
Здравствуйте, Sir Wiz, Вы писали:

SW>Здравствуйте, <Аноним>, Вы писали:


А>>по сути тоже самое, но вроде как изящнее.


SW>Да, спасибо. идея мне нравится.


SW>Только, к сожалению в существующем проекте так сделать не получится — не смогу я объяснить заказчику, почему из-за моих эстетических потребностей отлично работающий модуль станет работать медленнее


мы тут копируем только ссылки на объекты (т.е. копирования строки не происходит) + все необходимые объекты создаются на стеке!!! Поэтому если эта операция происходит не более 100000 раз в секунду, то заметить разницу просто не возможно ну разьве что утилитами
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.