Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
2 / 2 / 4
Регистрация: 28.06.2013
Сообщений: 56

Достать нужный объект из контейнера

28.05.2014, 11:05. Показов 1001. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Возник вопрос, отчасти я сам решил(получил нужный результат), но очень коряво.

Мне нужно достать нужный объект из контейнера на абстрактный класс в методах классов наследниках. Если вкратце, то у меня есть контейнер указателей на абстрактный класс, в котором хранятся различные объекты классов наследников, в моём случае это класс "Метеорит" и "Лазер", со временем будут ещё. Хотелось бы реализовать взаимодействие между ними как то так

C++
1
2
3
4
5
6
7
8
9
extern std::vector<CObject*> Objects;
 
    for(int i = 0; i < (int)Objects.size(); i++)
    {
        for(int j = 0; j < (int)Objects.size(); j++)
        {
            Objects[i]->Collision(Objects[j]);
        }
    }
То есть в зависимости от того какой объект в качестве аргумента передаётся, то и происходит с объектами.

Сейчас у меня как ни странно всё работает - пока видов объектов всего 2.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// абстрактный класс
class CObject
{
virtual void Collision(CObject* Object) = 0;
}
// класс наследник
class CLaser : public CObject
{
friend class CMeteor;
    void Collision(CObject* Object);
    bool Collision(CMeteor* Meteor); 
}
 
class CMeteor : public CObject
{
 
}
// Объявления методов CLaser
void CLaser::Collision(CObject* Object)
{
    CMeteor* Meteor;
    Meteor = (CMeteor*)Object;        
 
    if(Collision(Meteor) == true)
        Object->DestroyObject();
 
}
 
bool CLaser::Collision(CMeteor* Meteor)
{
    if(LaserHit(Meteor->Matrix, Meteor->MeteorSpeed, Meteor->MeteorRadius) == true)
        return true;
    else return false;
}

Meteor = (CMeteor*)Object;
Насколько законное такое присваивание типа? Что будет с объектами из контейнера, которые не CMeteor типа? И можно ли каким то образом проверить какой объект какого типа мы получаем в качестве аргумента, чтобы не лепить такие грабли? Чтобы сложность проверки была линейная - N Объектов - N проверок, а не увеличивалась от количества типов содержащихся в контейнере.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.05.2014, 11:05
Ответы с готовыми решениями:

Как достать указатель на объект из контейнера set
Имеется вот такой код #include &quot;stdafx.h&quot; #include &lt;string&gt; #include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;set&gt; ...

Если объект добавлять в 2 контейнера, то в них будет ссылка или новый объект?
Есть объект - obj. Последовательно добавляю его в два контейнера container1.add(obj); container2.add(obj); Если я удалю...

Достать нужный кадр
Добрый день. Подскажите как из кода AS перейти на нужный кадр шкалы времени.

9
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
28.05.2014, 11:57
Skaarj, dynamic_cast, но это все не очень честно говоря хорошо. Можно визиторы реализовать, но кол-во визиторов будет зависит от реального кол-ва классов, то есть много кода, если много классов.
По-хорошему в С++ простого решения данной траблы нет.
1
2 / 2 / 4
Регистрация: 28.06.2013
Сообщений: 56
28.05.2014, 13:10  [ТС]
Спасибо за наводку. Ввёл новую виртуальную функцию и определил для каждого наследника. В моём случае не так уж и много классов, так что вполне нормальный вариант. И главное dynamic_cast стал работать как надо - до этого выбивал при не совпадение типов
Я так понимаю это и есть визиторы?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CObject
{
virtual char* ObjectType() = 0;
};
 
class CLaser : public CObject
{
      char* ObjectType() { char *s; s = "Laser"; return s;}
};
 
class CMeteor : public CObject 
{
      char* ObjectType() { char *s; s = "Meteor"; return s;}
};
И проверяю тип
C++
1
2
3
4
5
6
    if(Object->ObjectType() == "Meteor")
    {
        CMeteor* Meteor = dynamic_cast<CMeteor*>(Object);
        if(Collision(Meteor) == true)
            Object->DestroyObject();
    }
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
28.05.2014, 13:36
Skaarj, Нет, это не визиторы.
ObjectType предельно бесполезен, ибо dynamic_cast вернет 0, если тип не совпадает.

C++
1
2
3
4
if ((CMeteor* Meteor = dynamic_cast<CMeteor*>(Object))
{
    // Object really has type Meteor*.
}
Добавлено через 6 минут
Прочитать про Посетитель можно тут: http://ru.wikipedia.org/wiki/%... 8%D1%8F%29

Добавлено через 3 минуты
Хотя наверное тут лучше будет какая-никакая реализация мультиметодов.
1
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
28.05.2014, 13:42
ForEveR, решение есть - выбросить из головы наследование, отделить физику от прочей логики объекта. Например,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class BBody{
  leftBound, rightBound, topBound, bottomBound, farBound, nearBound;
}
class CObject{
  virtual BBody getBoundingBody();
//а возможно даже не virtual, а вполне хранящееся в родителе поле BBody body_;
};
 
for(i=lasers.begin(); i!=lasers.end(); ++i)
  for (j=meteors.begin(); j!= meteors.end(); ++j)
    if(Intersects(i->getBoundingBody(), j->getBoundingBody() )){
       //...
    }
1
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
28.05.2014, 13:47
Kuzia domovenok, Я не могу уловить суть данного решения, ибо код написан непонятно как. Можно чуть подробнее все же? Если бы BBody был бы enum я бы еще что-то мог понять (хотя это никак не решает проблему и не избавляет от RTTI), но в этом случае как-то нет.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
28.05.2014, 14:00
Цитата Сообщение от ForEveR Посмотреть сообщение
Если бы BBody был бы enum я бы еще что-то мог понять (хотя это никак не решает проблему и не избавляет от RTTI), но в этом случае как-то нет.
какой ещё енум? ты не можешь понять, потому что зациклился на своих кастах, ртти, проблеме определения, что метеор, а что лазер и.т.д. и думаешь, что BBody тоже к чему-то из этой области относится.
Объясняю - мой код вообще не эту проблему решает и не отвечает на этот вопрос.
Объясняю далее - каждый объект содержит Bounding Body. Обычный объект, который ни от чего не наследуется, который содержит например, просто AABB метеора. Что не ясно?
Вот когда у тебя пошли использоваться какие-то стрёмные касты и попытки зачем-то выяснить в динамике тип объекта - вот это уж точно говнокод пошёл.
C++
1
2
3
4
5
for(i=lasers.begin(); i!=lasers.end(); ++i)
  for (j=meteors.begin(); j!= meteors.end(); ++j)
    if(Intersects(i->getBoundingBody(), j->getBoundingBody() )){
       //...
    }
вот тут что не ясно может быть и зачем могут понадобиться касты?
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
28.05.2014, 14:05
Kuzia domovenok, То есть лазеры отдельно, метеоры отдельно, что-то там еще отдельно? Ну, вцелом все ясно. Уход в сторону уютной сишечки, почему бы и нет.

Добавлено через 1 минуту
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Вот когда у тебя пошли использоваться какие-то стрёмные касты и попытки зачем-то выяснить в динамике тип объекта - вот это уж точно говнокод пошёл.
Ничем не обоснованное заявление. Проблемы бывают разные и решаются они по разному.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
28.05.2014, 14:10
Цитата Сообщение от ForEveR Посмотреть сообщение
Уход в сторону уютной сишечки, почему бы и нет
это чистейшее ООП! Что по-твоему тогда?
i->getBoundingBody()
Типичная композиция. BoundingBody - поле класса CObject, а от класса CObject наследуются остальные!
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
28.05.2014, 14:15
Kuzia domovenok, Окей, с доводами согласен. А как это решает проблему ТС? Предоставь пожалста код, который выполняет то что хотел ТС, с теми изменениями которые ты предложил.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.05.2014, 14:15
Помогаю со студенческими работами здесь

Достать нужный файл из директории
Как можно достать файл из существующей директории? Название файла с расширением выводится в dbedit, нужно по нажатию кнопки открыть файл с...

Достать, объявить объект
var comment = { int: function(){ data.messeg('тектс'); // Собственно объект data он есть, но его не достать, не видит когда...

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

Что можно возвратить из функции если нужный объект не создан
Добрый день! Есть функции, которые возвращают указатели на двумерные массивы, но заполнение и создание массива происходит после...

Как достать объект-контейнер, а не его элемент
Добрый вечер всем. Возник вопрос. Я читал Страуструпа и на одной из его глав, есть упражнение по созданию класса-контейнера, в...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных через динамический список в справочнике
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru