Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614

Иерархия объектов. Привязывание/отвязывание узлов

04.03.2017, 21:19. Показов 1001. Ответов 1
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток, Господа. Возникла проблема, в решении которой, никак не могу разобраться.
Итак, в прикрепленной мною картинки, видна иерархия объектов. Каждый объект знает о своем Node объекте и о своем Parent объекте.
Необходимо реализовать методы для прикрепления/открепления дочерних объектов.
Вот мой класс объекта:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    class BTSGameObject
    {
    public: 
        ... 
        void                                                setParent( BTSGameObject* parent );
        BTSGameObject*                                      getParent()  const;
        void                                                setNode( BTSGameObject* node );
        BTSGameObject*                                      getNode()    const;
        const std :: map<std :: string, BTSGameObject*>&    getChilden() const; 
        void                                                addChild( BTSGameObject* object );      // Вот эту нужно реализовать функцию
        void                                                removeChild( BTSGameObject* child );    // И вот эту
        ...
    private:
        std :: map<std :: string, BTSGameObject*>           _children;
        BTSGameObject*                                      _parent;
        BTSGameObject*                                      _node;
        ...
    };
Сложность в том, что мне нужно сделать так, чтобы при откреплении дочернего объекта(removeChild( BTSGameObject* child )), он переписывался на Node объект.
Пишу так:
C++
1
2
3
4
5
6
7
8
9
void BTSGameObject :: removeChild( BTSGameObject* child )
{
    auto it = _children.find( child -> getName() );
    if( it != _children.end() )
        _children.erase( it );
 
    child -> setParent( _node );    // Устанавливаем родителя как Node объект
    _node -> addChild( child );     // Добавляем к Node объекту дочерний
}
Теперь нужно естественно реализовать addChild( BTSGameObject* child ):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void BTSGameObject :: addChild( BTSGameObject* child )
{
    const auto& it = _children.find( child -> getName() );
    if( it != _children.end() )
        return;
    
    ...
    
    // Добавляем дочерний объект
    _children.insert( std :: pair<std :: string, BTSGameObject*>( child -> getName(), child ) );
    child -> setParent( this );
 
    ...
}
Все вроде работает...но как бы не так...
Допустим я хочу присоединить объект 2 к объекту 6. Но объект 2 имеет уже родителя(объект 1) и находится у него в списке естественно.
Значит мне нужно как-то его отписать от него, и добавить в объект 6.
А как отписать? Естественно с помощью метода removeChild( BTSGameObject* child ), зачем мы его писали тогда?
И тут возникает проблема:
1. При вызове addChild( BTSGameObject* child ) у объекта 6 и передачи туда объекта 2, происходит вызов removeChild( BTSGameObject* child ) для родителя объекта 2(объект 1), чтобы удалить его из списка.
Это в свою очередь вызывает опять addChild( BTSGameObject* child ), но только для Node объекта...а она removeChild( BTSGameObject* child )...ну а дальше Вы поняли...
2. Если я поставлю ограничение в методе addChild( BTSGameObject* child ), вот такое:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void BTSGameObject :: addChild( BTSGameObject* child )
{
    const auto& it = _children.find( child -> getName() );
    if( it != _children.end() )
        return;
    
    if( child -> getParent() != _node )
        child -> getParent() -> removeChild( child );   
    ...
    
    // Добавляем дочерний объект
    _children.insert( std :: pair<std :: string, BTSGameObject*>( child -> getName(), child ) );
    child -> setParent( this );
 
    ...
}
тоесть мы можем удалять из родительского объекта только в том случае, если родительский не является нойдовым. Это привнесет новых проблем.
А именно:
При вызове addChild( BTSGameObject* child ) у объекта 6 и передачи туда объекта 2, происходит проверка, неявляется ли родитель объекта2(объект 1) нойдовым; как мы видим, он не является нойдовым, следовательно происходит вызов removeChild( BTSGameObject* child ) для родителя объекта 2(объект 1), чтобы удалить объект 2 из списка.
Это в свою очередь устанавливает нового родителя для объекта 2 - Node объект, и вызывает опять addChild( BTSGameObject* child ), но только для Node объекта.
Заходим опять в addChild( BTSGameObject* child ) и выполняем проверку. Проверка говорит о том, что родитель является Node объектом, следовательно идем далее: добавляем в список Node объекта объект 2.
Затем идет выход из метода addChild( BTSGameObject* child ) и метода removeChild( BTSGameObject* child ), и возвращаемся к первому вызову addChild( BTSGameObject* child ) для объекта 6. Далее происходит добавление в список объекта 2 для объекта 6 и установка родителя для объекта 2 - объект 6.

И что мы видим? Теперь объект 2 находится в списке у Node объекта и у объекта 6, хотя мы добавляли его только для объекта 6.

Взрыв мозга...Может подскажете что-нибудь по этому поводу?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.03.2017, 21:19
Ответы с готовыми решениями:

Иерархия геометрических объектов
Иерархия геометрических объектов наследием: класс точка -&gt; класс треугольник -&gt; класс квадрат -&gt; класс прямоугольник. на си++ и mfc...

Комопзиция объектов/иерархия классов
в общем нигде не могу найти внятного объяснения в виде кода, все очень поверхностно везде написано.Может кто знает место где есть хороший...

Иерархия объектов для battle city
Пишу игру Танчики ООП на С++. для начала стоит задача создать иерархию объектов а потом уже и классов. вот создал для объектов....

1
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
04.03.2017, 21:21  [ТС]
Вот картинка
Миниатюры
Иерархия объектов. Привязывание/отвязывание узлов  
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.03.2017, 21:21
Помогаю со студенческими работами здесь

Иерархия объектов и динамические списки внутри класса
собственно есть задание Я вроде как понимаю задание но и не понимаю). Решил написать сюда. План действий. 1. Создаю абстрактный...

Иерархия геометрических объектов: клас точка->класс квадрат->класс прямоугольник
Иерархия геометрических объектов: класс точка-&gt;класс квадрат-&gt;класс прямоугольник. Построить эту иерархию наследованием.. Прошу помочь -...

Удаление всех узлов и защита от отсутствие узлов в односвязном списке
Здравствуйте. Помогите мне пожалуйста разобраться с проблемой. У меня получилось сделать добавление узла (в начало, в конец, перед и после...

Иерархия объектов и группа, итераторы
Порядок выполнения работы. 1. Дополнить иерархию классов лабораторной работы № 2 классами “группа”. Например, для предметной области...

Теория. Иерархия объектов VBA.
Расположите оъекты Word в соответствии с их местом, занимаемым в иерархии объектов VBA, начиная с верхнего: Application Document Word...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru