Russian Qt Forum

Программирование => Общий => Тема начата: Igors от Сентябрь 10, 2009, 17:50



Название: Sets of Objects
Отправлено: Igors от Сентябрь 10, 2009, 17:50
Добрый день

Вопрос по "проектированию", как организовать данные

Есть массив (список, вектор) разнородных объектов. Пользователь может создавать/удалять/редактировать произвольные "подмножества" (sets) объектов из общего списка. Set может быть пустым, один объект может входить в любое число sets. Сам объект в set копироваться не должен, set должен обеспечивать только доступ к нему (например через указатель).

Вопрос: как сохранить set в файл и прочитать из файла? Или более общий вопрос: как организовать данные для таких sets?



Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 10, 2009, 18:02
Сохранить отдельный set или исходное множество со всеми прожденными sets?


Название: Re: Sets of Objects
Отправлено: Igors от Сентябрь 10, 2009, 18:22
Сохранить отдельный set или исходное множество со всеми прожденными sets?
Само собой, исходное множество объектов сохраняется. Но кроме этого нужно сохранить все sets созданные пользователем (без повторного сохранения самих объектов). Принцип: set указывает/ссылается на данные (а не копирует их)


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 10, 2009, 18:34
Сохранить отдельный set или исходное множество со всеми прожденными sets?
Само собой, исходное множество объектов сохраняется. Но кроме этого нужно сохранить все sets созданные пользователем (без повторного сохранения самих объектов). Принцип: set указывает/ссылается на данные (а не копирует их)
У меня в проекте решается такая задача.
Принцип прост. Сохраняешь(сериализуешь) объекты для основного множества и ссылки(идентификаторы) на них для sets.
Если нужны подробности, задавай вопросы, я на этом уже "съел стайку собак" :)


Название: Re: Sets of Objects
Отправлено: Igors от Сентябрь 10, 2009, 18:52
У меня в проекте решается такая задача.
Принцип прост. Сохраняешь(сериализуешь) объекты для основного множества и ссылки(идентификаторы) на них для sets.
Если нужны подробности, задавай вопросы, я на этом уже "съел стайку собак" :)
Хорошо, тогда начнем с первой с первой собаки :) Как "сериализовать" объекты и что то за идентификаторы (ID)? Как/когда Вы их создаете?


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 10, 2009, 19:25
Хорошо, тогда начнем с первой с первой собаки :) Как "сериализовать" объекты и что то за идентификаторы (ID)? Как/когда Вы их создаете?
Это уже 2 или 3 собаки :)
1) Сериализуем простые типы данных:
   byte
   integer разного размера
   real
   boolean
   байтовый массив определенной длины
2) Сериализуем ссылки. Ссылка это идентифакатор(у меня числовой) на сериализуемый  объект
3) Сериализуем объекты. У меня все сериализуемые объекты имеют общего предка, но возможны и другие подходы.
  Объект сериализует свои поля(не обязательно все), различаются:
  - простые типы данных (1)
  - объекты (3)
  - ссылки на объекты (2)
  - NULL
Возможен подход когда не различаются объект и его ссылка, у меня так было в начале.
  Но,
    - это труднее реализовать
    - труднее сохранять, требуется дополнительная обработка на то, что сохранен ли уже объект, если не сохранен, то сериализуем как объект, если сохранен, то сериализуем как ссылку.
    - труднее восстанавливать, требуется дополнительная обработка на то, что создан ли уже объект.
    - черевато большим кол-вом ошибок.
Поэтому, лучше различать объекты и ссылки на них.
  - Объекты - там где создаются/удаляются
  - Ссылки - где сохраняются указатели на созданные объекты
4) Сериализуемые объекты различаются на 2 типа
  - создаваемый - объект создается при чтении, может быть только указателем и до чтения == NULL
  - запоняемый - до чтения объект уже создан(например в конструкторе другого объекта либо автоматически), необходимо только заполнить(прочитать) его поля


Название: Re: Sets of Objects
Отправлено: Igors от Сентябрь 10, 2009, 19:51
Спасибо за подробный ответ. Мне ясно что Вы сохраняете(читаете) в потоке ТИП объектов/данных, это неизбежно так или иначе. Но неясно как Вы поддерживаете связки при записи/чтении. Давайте на простом примере:

Есть 3 объекта, например QString. Пользователь создал set в который входят 2-я и 3-я строка. Вопросы:

Как организовать данные самого set?
Что и в каком порядке будет писАться/читаться?



Название: Re: Sets of Objects
Отправлено: BRE от Сентябрь 10, 2009, 20:10
Есть 3 объекта, например QString. Пользователь создал set в который входят 2-я и 3-я строка. Вопросы:

Как организовать данные самого set?
Что и в каком порядке будет писАться/читаться?
Напишу свои мысли по этому вопросу:
Есть пул указателей на объекты, пусть для этого используется QList<Base*> pool;
В нем содержаться все возможные объекты. При создании нового объекта он сохраняется в пуле. Пул является владельцем объектов, т.е. при уничтожении пула будут уничтожены и сами объекты. Набор не владеет объектами, т.е. при его разрушении уничтожается сам набор, а объекты не трогаются.

pool.append( new Str( "String # 1" ) );
pool.append( new Str( "String # 2" ) );
pool.append( new Str( "String # 3" ) );

// В наборе set1 хранятся указатели на 2 и 3 строку
QList<Base*> set1;
set1.append( m_pool[ 1 ] );
set1.append( m_pool[ 2 ] );

// В наборе set2 хранятся указатели на 1 и 3 строку
QList<Base*> set1;
set1.append( m_pool[ 0 ] );
set1.append( m_pool[ 2 ] );

При хранении в памяти в качестве уникального ключа используется адрес размещения объекта. При хранении на диске в качестве ключа используется порядковый номер сохраненного объекта.

Для сохранения:
* Сохраняем последовательно все объекты из пула, в том порядке в котором они лежат.
* Сохраняем наборы

Структурный вид файла:
[количество объектов в пуле]
[объект # 0] // String # 1
[объект # 1] // String # 2
[объект # 2] // String # 3
[количество наборов]
[Набор 1]
  [int: 1] // индекс объекта в пуле
  [int: 2]
[Набор 2]
  [int: 0]
  [int: 2]


Название: Re: Sets of Objects
Отправлено: Igors от Сентябрь 10, 2009, 20:28
При хранении в памяти в качестве уникального ключа используется адрес размещения объекта. При хранении на диске в качестве ключа используется порядковый номер сохраненного объекта.
Да вот именно так оно и сделано :) И хотя это работает уже много лет - это реально "плохо" (очень мягко говоря). Проблемы лезут из всех щелей в такой схеме, деваться некуда - нужно переделывать. Пока точно не знаю как, давайте людей послушаем


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 10, 2009, 20:31
Правильно, спасибо BRE! Принцип именно этот, но реализация может быть разная.
Ссылаюсь на конкретную, мою, реализацию.
У меня:
1) Сериализуемый класс наследуется от общего предка RW
2) Сериализуемый класс(за исключением абстрактных предков) должен имееть макро вставку(аналогично Q_OBJECT в QT) для мета-объектной идентификации(нужна при чтении/восстановлении объектов из потока), но с именем класса, примерно так:
Код:
class TFileID : public RW {
    SBW_CLASS_ID(TFileID)
...
...
}
Плюс к этому еще кое-что, прописывается вне классов, но тоже очень простое(я обхожусь без "MOC" механизмов реализованных в QT, которые требуют обработку перед компиляцией)
3) Каждый сохраняемый(реальный объект) перед сохранением получат уникальный ID(в моем случае числовой), который записывается в поток вместе с данными объекта
4) При сохранении объектов в некий список прописывается пара - адрес(указатель) объекта + его ID
5) При сохранении ссылки находим в таблице по адресу(указателю) его ID и соответственно(неким образом) сохраняем в потоке
6) Подобно при чтении


Название: Re: Sets of Objects
Отправлено: BRE от Сентябрь 10, 2009, 20:34
Да вот именно так оно и сделано :) И хотя это работает уже много лет - это реально "плохо" (очень мягко говоря). Проблемы лезут из всех щелей в такой схеме, деваться некуда - нужно переделывать. Пока точно не знаю как, давайте людей послушаем
Так а что за проблемы, рассказывай. Давайте вместе подумаем.
В этой системе нужно точно распределить кто может создавать объекты, кто их должен удалять, как их регистрировать в пуле и т.д.


Название: Re: Sets of Objects
Отправлено: Igors от Сентябрь 10, 2009, 20:52
Так а что за проблемы, рассказывай. Давайте вместе подумаем.
О проблемах тут можно целый роман написать :) Рассмотрим пару простеньких

1) Пользователь удаляет объект. Нужно пробежаться по всем set'ам и удалить указатель на удаляемый объект из каждого set'а. Как Вы знаете, я не фанат ООП, но это уж слишком даже для меня. Это как же получается, ВСЕ объекты должны знать о существовании set'ов?

2) Пользователь передумал и "возвращает объект взад" вызывая undo. Как поддержать откат? Какие данные заносить в стек undo? Давайте сохраним для undo все set'ы в которые объект входил? Не жирно ли?


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 10, 2009, 20:53
Далее(у меня).
Каждый неабстрактный класс унаследованный от RW должен определить для сериализации всего один виртуальный метод, пример:
Код:
void TFileID::reg(RWControl* control) {
// ParentForTFileID(control); // if necessary
  SBW_REG_DATA (File);
  SBW_REG_DATA (Hash);
  SBW_REG_INT (Size);
  SBW_REG_DATA (MTime);
}
Ее одной достаточно и для записи и для чтения!

Для сериализации  полей у меня определены следующие макросы:
SBW_REG_DATA(__value) {...} // для сериализации объектов
SBW_REG_BOOL(__value) {...} // для сериализации boolean(bit)
SBW_REG_INT(__value)  {...} // для сериализации integer от 8 до 64 битных
SBW_REG_ENUM(__value) {...} // для сериализации enum {}
SBW_REG_REAL(__value) {...} // для сериализации double
SBW_REG_OBJ(__value)  {...} // для сериализации создаваемых объектов
SBW_REG_REF(__value)  {...} // для сериализации ссылок на объекты
SBW_REG_BUFF(__value, __len) {...} // для сериализации буфера(массива байт)



Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 10, 2009, 21:04
1) Пользователь удаляет объект. Нужно пробежаться по всем set'ам и удалить указатель на удаляемый объект из каждого set'а. Как Вы знаете, я не фанат ООП, но это уж слишком даже для меня. Это как же получается, ВСЕ объекты должны знать о существовании set'ов?

2) Пользователь передумал и "возвращает объект взад" вызывая undo. Как поддержать откат? Какие данные заносить в стек undo? Давайте сохраним для undo все set'ы в которые объект входил? Не жирно ли?
Это никак не связано с записью/чтением(сериализацией) системы объектов в поток(например, запись в файл и восстановление из файла; или создание копии)!
Это совсем другая задача, вернее задачи.


Название: Re: Sets of Objects
Отправлено: BRE от Сентябрь 10, 2009, 21:05
1) Пользователь удаляет объект. Нужно пробежаться по всем set'ам и удалить указатель на удаляемый объект из каждого set'а. Как Вы знаете, я не фанат ООП, но это уж слишком даже для меня. Это как же получается, ВСЕ объекты должны знать о существовании set'ов?
Есть пул объектов (ObjPool).
Есть пул наборов (SetPool).

При создании набора (в конструкторе) он регистрируется в пуле наборов.

При создании объекта (в конструкторе) он регистрируется в пуле объектов, в деструкторе он:
* просит объект SetPool вычеркнуть его из всех наборов;
* просит объект ObjPool вычеркнуть его из пула объектов.

2) Пользователь передумал и "возвращает объект взад" вызывая undo. Как поддержать откат? Какие данные заносить в стек undo? Давайте сохраним для undo все set'ы в которые объект входил? Не жирно ли?
Возвращает объект из набора - удалили указатель на объект из набора.


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 10, 2009, 21:18
1) Пользователь удаляет объект. Нужно пробежаться по всем set'ам и удалить указатель на удаляемый объект из каждого set'а. Как Вы знаете, я не фанат ООП, но это уж слишком даже для меня. Это как же получается, ВСЕ объекты должны знать о существовании set'ов?
2) Пользователь передумал и "возвращает объект взад" вызывая undo. Как поддержать откат? Какие данные заносить в стек undo? Давайте сохраним для undo все set'ы в которые объект входил? Не жирно ли?
Igors, BRE! Это не относится к данной теме!
Igors, если желаешь обсудить эти вопросы, создавай отдельную тему. Не надо мешать все в одну кучу.


Название: Re: Sets of Objects
Отправлено: Igors от Сентябрь 10, 2009, 21:30
Это никак не связано с записью/чтением(сериализацией) системы объектов в поток(например, запись в файл и восстановление из файла; или создание копии)!
Это совсем другая задача, вернее задачи.
Мы сказали/утверждаем: set знает объект как указатель, в файле записан "индекс" объекта. Так мы решаем I/O. Понятно, но из этого же вытекают проблемы о которых я писал в предыдущем посте.

Возвращает объект из набора - удалили указатель на объект из набора.
Не понял как это связано с undo

Ладно, вот еще парочка проблем:

3) При чтении самих объектов не каждый из них может быть прочитан. Например, объект ссылается на файл а его на диске уже нет. Но если мы не добавим такой объект в ObjPool - "индексы" для set'ов улетят.

4) Пользователь хочет загрузить файл данных не удаляя текущие объекты. То есть просто "append". С "индексами" нужно что-то делать.

И.т.д, и.т.п. Конечно, все проблемы можно решить (я же и занимался их решением :)) но я прекрасно понимаю что это "латки".  Схема "указатель/индекс" больная/дефективная, ее нужно менять "в прынцыпе" а не латать.


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 10, 2009, 21:42
Это никак не связано с записью/чтением(сериализацией) системы объектов в поток(например, запись в файл и восстановление из файла; или создание копии)!
Это совсем другая задача, вернее задачи.
Мы сказали/утверждаем: set знает объект как указатель, в файле записан "индекс" объекта. Так мы решаем I/O. Понятно, но из этого же вытекают проблемы о которых я писал в предыдущем посте.
Да с какой стати они отсюда вытекают? Совершенно не связанные задачи!
Есть система объектов, сохраняем в поток, восстанавливаем из потока(как было или как хотим).
И всякие операции удаления, перемещения объектов в рамках системы(до ее сохранения или после чтения) никак с этим не связаны!
Записал систему в файл как есть. Делай с тем что в памяти что хочешь.
Создал  систему (прочитал из файла). Делай с тем что в памяти что хочешь.


Название: Re: Sets of Objects
Отправлено: BRE от Сентябрь 10, 2009, 21:49
Не понял как это связано с undo
Пользователь дал команду добавить объект в набор, в стек undo записали команду удалить объект из набора. Или я не понял вопрос.

3) При чтении самих объектов не каждый из них может быть прочитан. Например, объект ссылается на файл а его на диске уже нет. Но если мы не добавим такой объект в ObjPool - "индексы" для set'ов улетят.
Варианты:
1. Создать объект с флагом, что объект не валиден. После чтения удалить все не валидные объекты, они автоматически удаляться из всех наборов.
2. При чтении объектов сохранять индексы не валидных и не включать их в наборы.

4) Пользователь хочет загрузить файл данных не удаляя текущие объекты. То есть просто "append". С "индексами" нужно что-то делать.
Как правильно ты написал ниже, и это решается, если захотеть.  ;)
Если вначале продумать весь необходимый функционал, а потом приступить к реализации, думаю многих костылей можно будет избежать.

И.т.д, и.т.п. Конечно, все проблемы можно решить (я же и занимался их решением :)) но я прекрасно понимаю что это "латки".  Схема "указатель/индекс" больная/дефективная, ее нужно менять "в прынцыпе" а не латать.

Igors, BRE! Это не относится к данной теме!
Igors, если желаешь обсудить эти вопросы, создавай отдельную тему. Не надо мешать все в одну кучу.
Spectre, согласен, но уже начали обсуждать здесь. Может модераторы смогут разделить.


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 10, 2009, 21:49
3) При чтении самих объектов не каждый из них может быть прочитан. Например, объект ссылается на файл а его на диске уже нет. Но если мы не добавим такой объект в ObjPool - "индексы" для set'ов улетят.
Это никак не связано с сериализацией объекта имеющего поле "имя файла".
С таким же успехом, у тебя есть в памяти объект ссылающийся на файл, в какой-то момент файл был удален, ну и что, все точно также.
С другой стороны, никто тебе не запрещает во время чтения полей объекта из потока, проводить при необходимости нужные проверки.


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 10, 2009, 21:57
4) Пользователь хочет загрузить файл данных не удаляя текущие объекты. То есть просто "append". С "индексами" нужно что-то делать.
Загружается(сохраняется) целостная система объектов из потока.
Проблемы объединения(и возможности объединения) ее с другими системами, это уже другай задача и решается она для конкретных случаев.


Название: Re: Sets of Objects
Отправлено: Igors от Сентябрь 10, 2009, 22:14
1. Создать объект с флагом, что объект не валиден. После чтения удалить все не валидные объекты, они автоматически удаляться из всех наборов.
А если этот объект parent для других объектов и они рассчитывают на валидный parent? Ступив на "скользкий путь", мы должны по нему идти и идти. Почему мы создаем флаг "не валид"? Из идейных соображений? Вовсе нет, давайте признаемся - надо закрыть очередную дыру :)

Spectre, согласен, но уже начали обсуждать здесь. Может модераторы смогут разделить.[/quote]
Не могу с Вами согласиться. Если мы сказали - связки должны работать "по указателю", то мы себе и создали букет проблем которые потом будем решать и решать.

Использование "просто указателя" для серъезных данных (вне UI) плохо!

О боже, как кощунственно это звучит  :)


Название: Re: Sets of Objects
Отправлено: BRE от Сентябрь 10, 2009, 22:38
А если этот объект parent для других объектов и они рассчитывают на валидный parent? Ступив на "скользкий путь", мы должны по нему идти и идти. Почему мы создаем флаг "не валид"? Из идейных соображений? Вовсе нет, давайте признаемся - надо закрыть очередную дыру :)
Какие дыры?
Можно много придумывать, но проще огласить спецификации, что бы мы не гадали что это за объекты и какие у них могут быть свойства.
Что касается:
Цитировать
3) При чтении самих объектов не каждый из них может быть прочитан. Например, объект ссылается на файл а его на диске уже нет. Но если мы не добавим такой объект в ObjPool - "индексы" для set'ов улетят.
Если файла нет на диске и объект имеет подчиненные объекты, создаем объект, отмечая что данные в нем не валидны (файл с данным стерт). Место данных из файла выводим, например, иконку с фигой. Если же для объекта важен файл на диске и его нет, то мы обязаны прервать загрузку данных и вывести диагностическое сообщение.

Указатели используются как уникальный ключ, можно добавить еще один уровень косвенности и использовать не указатели, а какие нибудь идентификаторы. Но пока я не вижу причин для этого, но и полностью задачу я не знаю.


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 10, 2009, 22:47
1. Создать объект с флагом, что объект не валиден. После чтения удалить все не валидные объекты, они автоматически удаляться из всех наборов.
А если этот объект parent для других объектов и они рассчитывают на валидный parent? Ступив на "скользкий путь", мы должны по нему идти и идти. Почему мы создаем флаг "не валид"? Из идейных соображений? Вовсе нет, давайте признаемся - надо закрыть очередную дыру :)

Цитировать
Spectre, согласен, но уже начали обсуждать здесь. Может модераторы смогут разделить.
Не могу с Вами согласиться. Если мы сказали - связки должны работать "по указателю", то мы себе и создали букет проблем которые потом будем решать и решать.

Использование "просто указателя" для серъезных данных (вне UI) плохо!

О боже, как кощунственно это звучит  :)
1) Связь объектов между собой и динамика их отношений:
  - parent <-> children
  - object <-> ref
  - owner <-> children
Это твоя проблема которая зависит от условий твоей задачи и твоих ресурсов итд..., о которой здесь никто пока не знает.

2) Абстарктные высказывания типа "давайте признаемся - надо закрыть очередную дыру" или "то мы себе и создали букет проблем которые потом будем решать и решать", это от бессилия, лени или злости, и никакого отношения к делу не имеют. Так что давай последовательно и конкретно.

3)
Использование "просто указателя" для серъезных данных (вне UI) плохо!
О боже, как кощунственно это звучит  :)
А это вообще откуда вылезло. :o


Название: Re: Sets of Objects
Отправлено: Igors от Сентябрь 11, 2009, 15:22
1) Связь объектов между собой и динамика их отношений:
  - parent <-> children
  - object <-> ref
  - owner <-> children
Это твоя проблема которая зависит от условий твоей задачи и твоих ресурсов итд..., о которой здесь никто пока не знает.
Проблема безусловно моя, с этим не поспоришь :) Но она так же и общая, поскольку BRE, Вы и я - все мы используем один и тот же подход/метод для связок между объектами (различия в реализации).

Так что давай последовательно и конкретно.
Я описал 4 совершенно конкретных проблемы которых мне пришлось решать. Могу добавить еще (не вопрос :)). Или можем обсудить более детально любую из уже сказанных - выбирайте какую. Но во всех случаях Вы утверждаете что (поправьте меня если не так):

- это конкретные проблемы конкретной задачи, которые надо решать в рабочем порядке. 

Я с этим НЕ согласен и утверждаю: эти проблемы общие и вызваны принципиальными ошибками в проектировании связей между объектами. То что мы все используем ("указатель на используемый объект") разваливается  в первую очередь там где указатель исчезает: I/O и Undo. Но и без этого не сладко: все время приходится искать по всем данным "кто ссылается на меня". Потом делать то же для "каждого сославшегося". Это хотя и возможно (так оно сейчас и есть  :)) но жрет время и производит уродливый код (в огромных количествах)

Переформулирую вопросы (все данные описаны в этой теме, если что упустил - спрашивайте, добавлю)
Как мне сделать общий механизм чтобы:

- Undo восстанавливало не только объекты но и связки между ними?
- Загружать (безболезненно и без акробатики с индексами) не только объекты но и связки между ними?
- сообщать ссылающемуся о том что ссылка изменилась (по-умному, а не напрямую)?

Интересует (предлагаю обсудить) общий механизм который поможет во всем этом. Если же Вы считаете что это проблемы частные/локальные - просто не отвечайте.


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 11, 2009, 16:14
1) У меня куча разных объектов и разных базовых списков с ними, а также ссылок и списков со ссылками на эти объекты. И никаких проблем с невалидностью ссылок на объект после удаления его где-то(например в базовом списке) не возникает. Я просто не допускаю таких ситуаций! Удалил объект - удалил(или обнулил) ссылки на него, а как правило лучше наоборот сначала разбираемся со ссылками, а затем уже удаляем объект.
2) Не спорю, что в некоторых случаях это не удобно, но как правило такие случае возникают из-за плохого проектирования. В исключительных случаях можно пользоваться всякими "умными указателями" и им подобным вещам. Нужно ли это и какая модель того-же "умного указателя" или какого-нибудь "мультиссылочного супер-саморастворяемого :) объекта" необходима зависит от твоей задачи.


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 11, 2009, 16:42
Теперь по поводу undo/redo. Опять же все зависит от конкретной задачи! Сделать абстрактную систему объектов с операциями дабавления/удаления/перемещения/изменения + undo/redo безсмысленно!
- для текста это один механизм,
- для списка к примеру можно перемещать элементы в другой список для простого их восстановления потом в основном
- для сложной системы, также можно куда-то перемещать элементы и запоминать связи, а можно периодически(например на определенные операции) снимать копии системы целиком(для чего хорошо подходит сериализация)

- Undo восстанавливало не только объекты но и связки между ними?
Можешь снимать копии(через сериализацию или другими методами).

- Загружать (безболезненно и без акробатики с индексами) не только объекты но и связки между ними?
Сериализация.

- сообщать ссылающемуся о том что ссылка изменилась (по-умному, а не напрямую)?
Всякие "умные указатели" и "глупые объекты" :) и еже им подобная дребедень используемая как правило при плохом проектировании.
А на напрямую и не обязательно:
- можно например оповещать элементы системы (хотя бы через те же сигналы/слоты) об изменеии состояний связанных(или
взаимодействующих) с ними элементов.
- можно создавать отношения типа родитель-потомок


Название: Re: Sets of Objects
Отправлено: Igors от Сентябрь 11, 2009, 17:14
Я своего мнения не навязываю. Если у Вас в проекте таких злосчастных проблем нет - то и слава богу. Просто у меня они есть и уже достали конкретно  :P
Теперь по поводу undo/redo. Опять же все зависит от конкретной задачи! Сделать абстрактную систему объектов с операциями дабавления/удаления/перемещения/изменения + undo/redo безсмысленно!
Я и не претендую чтобы "чудесная система/механизм" за меня undo делал. А хочу просто писать undo разумно.  

- для текста это один механизм,
- для списка к примеру можно перемещать элементы в другой список для простого их восстановления потом в основном
- для сложной системы, также можно куда-то перемещать элементы и запоминать связи, а можно периодически(например на определенные операции) снимать копии системы целиком(для чего хорошо подходит сериализация)
Для меня всякое копирование исключено. Объекты должны быть реально удалены и указатели на них будут невалидны. Снимать копии системы мне тоже не подходит (боюсь диска не хватит). Давайте на том же простом примере:

Есть 3 объекта QString. Пользователь удалил 2-ю. Естественно, перед удалением мы записали ее в стек undo. Все хорошо, но эта строка входила в set(ы). Значит и указатели на нее в set'ах должны быть удалены. Как сказать undo что надо восстановить связки?


Название: Re: Sets of Objects
Отправлено: BRE от Сентябрь 11, 2009, 17:25
Есть 3 объекта QString. Пользователь удалил 2-ю. Естественно, перед удалением мы записали ее в стек undo. Все хорошо, но эта строка входила в set(ы). Значит и указатели на нее в set'ах должны быть удалены. Как сказать undo что надо восстановить связки?
Для выполнения это операции нужно выполнить два действия:
* Если в наборе есть указатель на этот объект - убрать указатель из сета;
* Удалить объект.

Для выполнения undo также нужны два действия:
* Создать объект
* Добавить указатель на него в сет.

Какие проблемы?  :)


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 11, 2009, 18:08
Для меня всякое копирование исключено. Объекты должны быть реально удалены и указатели на них будут невалидны. Снимать копии системы мне тоже не подходит (боюсь диска не хватит). Давайте на том же простом примере:
- Естественно снимать копии можно только относительно небольших систем.
- Можно снимать копии отдельных частей системы, и при undo восстанавливать связи части с остальной системой.
Естественно что применение данного подхода разумно не во всех случаях.

Есть 3 объекта QString. Пользователь удалил 2-ю. Естественно, перед удалением мы записали ее в стек undo. Все хорошо, но эта строка входила в set(ы). Значит и указатели на нее в set'ах должны быть удалены. Как сказать undo что надо восстановить связки?
Опять абстрактная задача. Ну хорошо, приведу один абстрактный пример решения.

1) Базовый объект(аналогично QObject) назовем IObject в отличии от QObject может привязываться ко многим родителям, соответственно имеет как список детей, так и список родителей.
2) Аналогично QObject, при удалении IObject, в деструкторе, удаляет себя из списка всех родителей вызовом метода "removeFromAllParents", это метод публичный и может быть вызван без деструкции объекта(отвязка от родителей)
3) Родитель, в зависимости от его типа, может так-же вызвать removeFromAllParents ребенка и после уничтожить его, или просто вызвать метод ребенка removeFromParent(this)
4) Можно для IObject иметь только одного Главного родителя(котрый разрушает) и список Дополнительных родителей(которые просто связаны) с ним.

Дальше развивать не буду. Подобные схемы взаимодействия объектов решают твою проблему удаления из sets при удалении из главного set. Или другую задачу, разрушение объекта при удалении из всех sets(или последнего который его содержал). Еще решаются проблемы аналогичные оповещению всех(или части) родителей об изменении состояния объекта

====
Теперь по поводу примера.
Сделай классы IMainSet, и ISet. С Каждым добавляемым IObject связан флаг актуальности (int), если он 0, то IObject актуален(содержится в set), если нет, то IObject отброшен. флаг типа int для отслеживания уровней отброшенности.
IMainSet имеет метод destroyObjects(int level=0), разрушает все IObject с флагом >= level. Метод removeObject не удаляет объект, а меняет его флаг актуальности.
IMainSet - для главного предка, ISet - второстепенных.
Используя систему оповещения IObject всех своих родителей об изменении, легко автоматически сменить актуальность объекта во всех sets одновременно.
Это просто набросок, захочешь сделаешь как надо.
Дальше развивать не буду, устал. :(



Название: Re: Sets of Objects
Отправлено: Igors от Сентябрь 11, 2009, 18:11
Для выполнения undo также нужны два действия:
* Создать объект
* Добавить указатель на него в сет.

Какие проблемы?  :)
В какой сет(ы)? На каком месте в этом set(е) должен быть указатель на восстанавливаемый объект?


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 11, 2009, 18:29
Кстати, твоя задача, вернее ее некоторая разновидность(поскольку твоя абстрактна и ни к чему не привязана), вполне может быть решена через "Model-View-Controller" (я не имею ввиду QT-ную Model-View, а говорю про шаблон проектирования).

Если нет особого желания эксперементировать, разрабатывать свои схемы взаимодействий обектов(что вообще то очень полезно для развития), почитай про "Шаблоны(Паттерны) проектирования". http://ru.wikipedia.org/wiki/Паттерны_проектирования (http://ru.wikipedia.org/wiki/Паттерны_проектирования). Там есть и список литературы.



Название: Re: Sets of Objects
Отправлено: Igors от Сентябрь 11, 2009, 18:45
Есть 3 объекта QString. Пользователь удалил 2-ю. Естественно, перед удалением мы записали ее в стек undo. Все хорошо, но эта строка входила в set(ы). Значит и указатели на нее в set'ах должны быть удалены. Как сказать undo что надо восстановить связки?
Опять абстрактная задача. Ну хорошо, приведу один абстрактный пример решения.
Видимо у нас с Вами различное понимание абстракции :)

- 3 объекта QString - разве это абстрактно?  По-моему - это предельно конкретно  :)

- Есть set'ы, BRE предложил QList <QObject *> для set'ов. Хорошо, по существу так оно (сейчас) и есть. Оформляем:

typedef QList <QObject *>  TObjectList;
typedef QList <QObject *>  TSel;
typedef QList <TSet>         TSelList;

TObjectList theObjects;         // all objects in task
TSetList theSets;                 // all sets in task

При активности пользователя случилось:

theObjects.append("One");
theObjects.append("Two");
theObjects.append("Three");
...
theSets[selectedSet].append(theObjects[selectedObject]);  //  добавили selectedObject в selectedSet

Никак не могу понять, ЧТО неясно и зачем обзывать очевидные вещи абстракцией? :)
Если тема Вас не интересует - просто не отвечайте
Если интересует - отвечайте по существу а не "взагалi"  :)





Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 11, 2009, 19:14
Если честно, мне это надоело. Вы не потрудились даже прочитать и обдумать, то что было после этой фразы:
Опять абстрактная задача. Ну хорошо, приведу один абстрактный пример решения.
на написание чего я убил кучу своего времени и вы мне еще кидаете какие-то упреки:
Если тема Вас не интересует - просто не отвечайте
Если интересует - отвечайте по существу а не "взагалi"  :)

Далее
Никак не могу понять, ЧТО неясно и зачем обзывать очевидные вещи абстракцией? :)
Абстракция это именно, то что вы дали, поскольку небыло описано конкретной решаемой задачи. Подобных вещей можно много понапридумывать, но пока нет конкретной задачи, не может быть и конкретного решения, а абстрактное я вам привел.


Название: Re: Sets of Objects
Отправлено: BRE от Сентябрь 11, 2009, 19:15
В какой сет(ы)? На каком месте в этом set(е) должен быть указатель на восстанавливаемый объект?
Сообразил.
Посмотри такой паттерн как Command. Найдешь все ответы на свои вопросы.


Название: Re: Sets of Objects
Отправлено: Igors от Сентябрь 11, 2009, 19:40
Посмотри такой паттерн как Command. Найдешь все ответы на свои вопросы.
Мне кажется Вы несколько увлеклись "ролей учителя" :)
Я говорю о конкретных проблемах которые я испытал на своей шкуре, а не вычитал в умной книге. Мое мнение наивно и.т.п.? Очень может быть, я это переживу :) Но я хотел бы видеть/слушать реальных пацанов которые так же "поползали на брюхе"  как и я со всеми этими заморочками. А мнение "абстрактных теоретиков" которые сами этого не делали но что-то слышали - ну оно столько же и стОит  :)

Примите мои искренние извинения и.т.п. за то что я поднял "неудобную" тему
Будьте здоровы, умолкаю


Название: Re: Sets of Objects
Отправлено: BRE от Сентябрь 11, 2009, 19:49
Но я хотел бы видеть/слушать реальных пацанов которые так же "поползали на брюхе"  как и я со всеми этими заморочками.
Да ты еще никуда не "ползал", реальный пацан.   ;)  :) ;D

А мнение "абстрактных теоретиков" которые сами этого не делали но что-то слышали - ну оно столько же и стОит  :)
Да кое что делали, и на "крутых" программеров, которые ничего не умеют и не хотят учиться, я уже насмотрелся... Еще со времен FIDO. Старенький я уже, такие заявления уже давно не впечатляют  :)


Название: Re: Sets of Objects
Отправлено: spectre71 от Сентябрь 11, 2009, 20:24
Мне кажется Вы несколько увлеклись "ролей учителя" :)
Я говорю о конкретных проблемах которые я испытал на своей шкуре, а не вычитал в умной книге. Мое мнение наивно и.т.п.? Очень может быть, я это переживу :) Но я хотел бы видеть/слушать реальных пацанов которые так же "поползали на брюхе"  как и я со всеми этими заморочками. А мнение "абстрактных теоретиков" которые сами этого не делали но что-то слышали - ну оно столько же и стОит  :)

Примите мои искренние извинения и.т.п. за то что я поднял "неудобную" тему
Будьте здоровы, умолкаю
Тебе пытались помочь, ты этого не ценишь. :(
Твои заморочки: "которые ты испытал на своей шкуре" - это твои проблемы, учись - пиши - учись.
И про "абстрактных теоретиков" - что ты сам сделал, можешь показать, дать ссылочку?


Название: Re: Sets of Objects
Отправлено: Igors от Сентябрь 11, 2009, 21:09
Пацаны, давайте не понтоваться а давайте говорить по делу. Не буду я перед Вами отчитываться в каких конторах я работал последние 10(20) лет - ни к чему это. Никто медалей за прошлые заслуги не дает.

Я задал конкретные вопросы и предложил их обсудить. Со своей стороны я ничего не "высосал из пальца" ничего не придумывал а сказал то, что я реально имею в моем проекте. Чего ж на меня злиться? :) Что я не такой  как Вы? Ну так это нормально, люди должны быть разные  :)