Russian Qt Forum
Ноябрь 22, 2024, 16:43 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Выделить класс  (Прочитано 11184 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Май 28, 2016, 10:18 »

Добрый день

Есть такая структура (псевокод)
Код
C++ (Qt)
struct CNode {
...  
 int GetChildCount( void ) const;
 CNode * GetChild( int index );
 
// data
int mRow, mColumn;
...
};
И вот набегает набор методов посвященных манипуляциям с mRow, mColumn по чилдренам. Напр пересчитать все значения чтобы вставить новый чайлд в заданную строку/столбец. И наоборот, обеспечить нулевые минимальные строку/столбец после удаления чайлда. И другие. Это слабо связано с сущностью CNode и вполне может использоваться повторно (хотя пока такой необходимости нет).

Стоит ли сразу же выделить управление mRow/mColumn в отдельный класс? Если да то как это лучше сделать?

Спасибо
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #1 : Май 28, 2016, 10:30 »

а как mRow, mColumn связаны с index ?
что собой структура "физически" представляет?

если у Вас есть что то типа CNode::insertChild(int index, int row, int col), то по хорошему этот метод должен заботиться об обновлении всех зависимых значений после вставки (если я правильно идею понимаю). То же самое при удалении. А значит, по идее должен быть какой-либо внешний контроллер, который бы хранил список всех нодов и их "связи" и обновлял их при необходимости.
Но для этого надо знать структуру объектов.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Май 28, 2016, 11:07 »

а как mRow, mColumn связаны с index ?
что собой структура "физически" представляет?
То что и нарисовано вверху. По индексу получаем указатель на чайлда который имеет поля mRow, mColumn

если у Вас есть что то типа CNode::insertChild(int index, int row, int col), то по хорошему этот метод должен заботиться об обновлении всех зависимых значений после вставки (если я правильно идею понимаю). То же самое при удалении.
Понимаете правильно, но сейчас пересчеты строки/столбца - ф-ционал конкретного класса CNode (его методы).

А значит, по идее должен быть какой-либо внешний контроллер, который бы хранил список всех нодов и их "связи" и обновлял их при необходимости.
"Хранилище" - сам CNode, он предоставляет интерфейс (см выше) для получения числа чайлдов (айтемов) и доступа к их полям строка/столбец. Напрашивается класс использующий этот интерфейс - но не завязанный жестко на CNode

Но для этого надо знать структуру объектов.
Ну вот, опять проблемы с абстрактным мЫшлением Улыбающийся
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #3 : Май 29, 2016, 00:38 »

Ну вот, опять проблемы с абстрактным мЫшлением Улыбающийся

Но Вы же ожидаете конкретного ответа, а не абстрактного? Улыбающийся

Что такое row и column для айтема? по какому принципу они должны меняться, если куда-то вдруг вставляется еще один чайлд?
row и column это расположение айтема в какой-либо таблице, либо какие-либо внешние индексы, либо ... ?
Ничего этого из приведенного описания класса не видно.
О какой системе координат идет речь? Можно данные структуры предствить в "графическом" виде?
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Май 29, 2016, 07:03 »

row и column это расположение айтема в какой-либо таблице,
Да, в QGridLayout (юзер может таскать из одной ячейки в другую)
по какому принципу они должны меняться, если куда-то вдруг вставляется еще один чайлд?
Напр юзер захотел вставить айтем слева и/или сверху, для текущего QGridLayout это будет ячейка напр (-2, -5). Но такого QGridLayout не понимает, вот и надо пересчитать все row, column. Также есть требование: слева, справа (сверху, снизу) вокруг ячейки с айтемом должны быть хотя бы 1 пустой столбец (строка). И.т.д. На первый взгляд это кажется совсем простым, но мне почему-то пришлось повозюкаться с этим не один день  Улыбающийся Не то чтобы "огромный" код - но ощутимый. И вот я смотрю на него и думаю: ну а CNode здесь причем? А значит...  Непонимающий
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #5 : Май 29, 2016, 09:44 »

Я бы наверное row и column вынес из CNode в какой-нибудь CNodeManager, в котором бы имплементировалась вся логика переносов и пересчётов.
Почему так? Потому что row и column - это "внешние" атрибуты по отношению к ноде и могут меняться независимо от ее контента.

А в менеджере будет что то типа

typedef QPair<int,int> NodeIndex;
QMap<NodeIndex, CNode*> mNode;

ну и дальше делаем как то так:

myManager->insertNode(-2, -5, new CNode(..)); // ну а тут все координаты всех нодов переколбашиваем

читаем ноду:

CNode* node = myManager->getNode(-2, -5);

и т.д. "Усе через менежер".

Что касается чайлдов, я так понимаю - это просто ссылки на связанные ноды?
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Май 29, 2016, 11:34 »

Что касается чайлдов, я так понимаю - это просто ссылки на связанные ноды?
Да

Я бы наверное row и column вынес из CNode в какой-нибудь CNodeManager, в котором бы имплементировалась вся логика переносов и пересчётов.
Такой класс уже есть, но он занимается содержательной частью CNode (там еще масса всего). Поля mRow, mColumn в эту часть не входят - они как бы сами по себе, нет зависимостей от др членов CNode
typedef QPair<int,int> NodeIndex;
QMap<NodeIndex, CNode*> mNode;
Это не вносит никакой общности, по-прежнему завязано на CNode. Зато получаем новые мелкие заботы - напр при удалении CNode, сериализации и.т.п. Не вижу ничего плохого что CNode имеет поля строка/столбец
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #7 : Май 29, 2016, 13:30 »

А какое преимущество дает то, что mRow, mColumn находятся в ноде, а не в менеджере?
По вашему получается, что наоборот - сама по себе нода абсолютно не зависит от ее координат.
И когда на поле появляется новая нода - то в текущем варианте Вам надо проапдейтить все объекты-ноды.
А если бы их координаты жили  только в менеджере - в сами ноды лезть бы не пришлось, достаточно обновить индексы в менеджере, и все.
Да и сериализировать и удалять проще через менеджер, имхо. Проблем я не вижу,  только преимущества.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Май 30, 2016, 08:11 »

Да и сериализировать и удалять проще через менеджер, имхо. Проблем я не вижу,  только преимущества.
Тогда расскажите как сериализовать это

typedef QPair<int,int> NodeIndex;
QMap<NodeIndex, CNode*> mNode;

Что будем писать/читать в поток вместо указателя на CNode ?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Май 30, 2016, 08:22 »

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

Как-то уперлись в один вариант (связка по мапе). Ну а почему не простейшее наследование, напр
Код
C++ (Qt)
struct CNode : public GridMan {
...  
 int GetChildCount( void ) const;
 CNode * GetChild( int index );
 
// from GridMan
 virtual int GetCellCount( void ) const { return GetChildCount(); }
 virtual int & RowAt( int index )  { return GetChild(index)->mRow; }
 virtual int & ColumnAt( int index )  { return GetChild(index)->mColumn; }
 
// data
int mRow, mColumn;
...
};
Теперь GridMan - законно общий класс. Что Вы об этом думаете?
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #10 : Май 30, 2016, 10:07 »

По сериализации: вместо поинтера пишем id ноды.
Собсвтвенно, при десериализации восстанавливаем.
Без этого все равно никуда, как-то ж в любом случае надо связи восстанавливать.

По общему классу: а кто будет обновлять в этом случае "соседние" ноды, если текущая изменилась (перетащили там или удалили-вставили)? Откуда GridMan будет знать, кого обновлять, кого нет?
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Май 30, 2016, 12:07 »

По сериализации: вместо поинтера пишем id ноды.
Собсвтвенно, при десериализации восстанавливаем.
Без этого все равно никуда, как-то ж в любом случае надо связи восстанавливать.
Значит чтобы пользоваться такой конструкцией - надо обеспечить уникальное ID. Как-то это не очень "общо"  Улыбающийся

По общему классу: а кто будет обновлять в этом случае "соседние" ноды, если текущая изменилась (перетащили там или удалили-вставили)? Откуда GridMan будет знать, кого обновлять, кого нет?
Методы делающие содержательную работу (вставки/удаления) неизбежно есть, здесь они удачно ложатся в GridMan, напр
Код
C++ (Qt)
void GridMan::SetNodePos( int index, int row, int column );
В классе CNode я его не писал т.к. он не чисто виртуальный.
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #12 : Май 30, 2016, 13:01 »

Ну а как у Вас сейчас связь между нодами восстанавливается?
"Общий" ID можно тупо генерировать из поинтеров на ноды, тогда они гарантированно будут уникальными.

Насчет SetNodePos не совсем понимаю.
У Вас есть ноды 1,2,3,4.
Вы меняете позицию ноды 2. Кто будет пересчитывать позиции для 1,3 и 4?
Как это устроено?
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Май 31, 2016, 13:30 »

Насчет SetNodePos не совсем понимаю.
У Вас есть ноды 1,2,3,4.
Вы меняете позицию ноды 2. Кто будет пересчитывать позиции для 1,3 и 4?
Этот общий класс (GridMan) и будет, ведь у него есть доступ к позициям всех нодов (см перекрытые виртуалы)

Все-таки наследование мне здесь не очень нравится
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #14 : Май 31, 2016, 14:14 »

То есть КАЖДЫЙ GridMan, от которого наследуюется КАЖДАЯ нода, имеет доступ ко всем остальным нодам?
Как то совсем не хорошо...
Вынесите GridMan в отдельный класс, пусть он будет "один для всех".
А наследование тут не нужно.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.11 секунд. Запросов: 23.