Проблема с производным классом
|
|
Renus | Дата: Среда, 03 Ноября 2010, 11:22 | Сообщение # 1 |
почетный гость
Сейчас нет на сайте
| Всем привет. Щас спрошу вопрос, может я совсем туплю конечно, но что то с утра не додумывается... Есть список в который занесены все объекты, список хранит указатели на переменные собственного типа CObject, CObject в свою очередь базовый класс для всех объектов остальных игровых классов(CPlayer, CBullet и т.д.) Собсно вопрос в том как вытянуть значение внутренней переменной производного класса, пули например. Вот небольшой код для попадания пули по врагу: Code CrossIter=Obj_List.begin(); CObject* pObject; while(CrossIter!=Obj_List.end()) { pObject=*CrossIter; if (pObject->type=="bullet") { if (CheckColl(cbox, pObject->cbox)==true) { armor-=pObject->damage; // Вот тут надо получить доступ как к CBullet, а не CObject pObject->kill=true; } } CrossIter++; } Извините за кривую формулировку вопроса...
|
|
| |
ezhickovich | Дата: Среда, 03 Ноября 2010, 12:36 | Сообщение # 2 |
[Великий и могучий хозяинъ]
Сейчас нет на сайте
| Renus, тоесть если говорить проще, то ты хочешь получить доступ к элементам не определённым в базовом классе? Ты не можешь работать с ними т.к. компилятор не знает о их существовании... (как и о всех других неопределённых элементах) Но без выходных ситуаций не бывает... К примеру... (не самый удачный пример... хотя...) Можно реализовать функцию которая по имени параметра вернёт указатель на void... Вот так: virtual void* getParam (const char *name) = 0; // Для базового класса И: virtual void* getParam (const char *name) // Для дочернего класса { if (strstr (name, "damage") != NULL) return (void*)&damage; return NULL; } А использовать так: int d = *(int*)(obj->getParam("damage")); Вот примерно так...
Я: О великий повелитель этой ничтожной вселенной - сокращённо ЁЖ!
Сообщение отредактировал ezhickovich - Среда, 03 Ноября 2010, 12:47 |
|
| |
Renus | Дата: Среда, 03 Ноября 2010, 16:41 | Сообщение # 3 |
почетный гость
Сейчас нет на сайте
| В таком случае будет легче вынести все параметры объектов куда нибудь, и получать их через параметр базового класса. К примеру дать базовому классу переменную type, и определять ее в конструкторе при создании объектов, а через функции получать доступ к всяким параметрам... Опять навалил непонятно чего))) Интересно просто как люди делают, неужели нет более изящного подхода...?Добавлено (03.11.2010, 16:41) --------------------------------------------- Можно еще правда разделить списки, сделать отдельно для всех типов объектов и обрабатывать их по очереди, тогда будет не посредственный доступ ко всем параметрам производных классов... Жду предложений)))
|
|
| |
ezhickovich | Дата: Среда, 03 Ноября 2010, 16:53 | Сообщение # 4 |
[Великий и могучий хозяинъ]
Сейчас нет на сайте
| Renus, Ты предлагаешь в базовом классе определить все параметры дочерних классов, а в дочерних классах просто изменить уровень доступа к ним? Всё бы и хорошо если бы это исключало вероятность случайного использования закрытых переменных... Т.к. все переменные уже будут определены в родительском классе, то компилятор скушает сию мерзость как так и надо, но во время работы приложения есть очень большая вероятность наткнуться на ошибку доступа к памяти по адресу... Да и вообще этот подход сам по себе карявый... Quote (Renus) Можно еще правда разделить списки, сделать отдельно для всех типов объектов и обрабатывать их по очереди, тогда будет не посредственный доступ ко всем параметрам производных классов... Можно, но это лишняя работа как программиста, так и машины... А время=деньги...
Я: О великий повелитель этой ничтожной вселенной - сокращённо ЁЖ!
|
|
| |
Renus | Дата: Четверг, 04 Ноября 2010, 19:24 | Сообщение # 5 |
почетный гость
Сейчас нет на сайте
| Ну а как нормально получить указатель на объект производного класса, имея указатель только на его базовую часть...? Возможно у меня не правильна сама архитектура игрового цикла, если возникаю такие проблемы?))) И самое интересное что нигде подобной информации не найдешь, а все молчат, как будто это вселенская тайна Нет что бы какой то хороший человек сказал: "Я делаю так и так..." P. S. Пожалуйста, прошу всех игроделов-программистов, расскажите как вы храните игровые объекты и осуществляете взаимодействия между ними!!! Добавлено (04.11.2010, 19:24) --------------------------------------------- Ну вот, и все молчат...
|
|
| |
ezhickovich | Дата: Четверг, 04 Ноября 2010, 19:52 | Сообщение # 6 |
[Великий и могучий хозяинъ]
Сейчас нет на сайте
| Нуу... Я уже высказал свои идеи...
Я: О великий повелитель этой ничтожной вселенной - сокращённо ЁЖ!
|
|
| |
Faeton | Дата: Четверг, 04 Ноября 2010, 20:24 | Сообщение # 7 |
частый гость
Сейчас нет на сайте
| Добрый вечер. Необходимо привести к типу CBullet* armor-=( CBullet*)pObject->damage;
|
|
| |
ezhickovich | Дата: Четверг, 04 Ноября 2010, 21:25 | Сообщение # 8 |
[Великий и могучий хозяинъ]
Сейчас нет на сайте
| Мда, это уже точно получше того, что предлагал я =) Добавлено (04.11.2010, 21:25) --------------------------------------------- Хотя... Всё хорошо к месту... Поставлю плюс в репу...
Я: О великий повелитель этой ничтожной вселенной - сокращённо ЁЖ!
|
|
| |
Renus | Дата: Пятница, 05 Ноября 2010, 01:27 | Сообщение # 9 |
почетный гость
Сейчас нет на сайте
| Да не хочет, выдает ошибку, пишет что damage не является членом "CObject" По моему с указателями так нельзя...Добавлено (05.11.2010, 01:27) --------------------------------------------- Если решать вопрос таким способом, то нужно каким либо способом привести указатель к типу CBullet*, или получить его где нибудь... Ну, что то моих познаний тут не хватает(((
|
|
| |
Faeton | Дата: Пятница, 05 Ноября 2010, 09:22 | Сообщение # 10 |
частый гость
Сейчас нет на сайте
| Да не хочет, выдает ошибку, пишет что damage не является членом "CObject" Это уже из области фантастики. То что я предложил стандартное приведение типа указателя. В случае если объявленный указатель на некоторый класс, ссылается на объект дочернего класса, доступ к его методу можно получить лишь таким способом. Если же всё таки ругается компилятор значит ошибка в другом месте. Например в списке действительно хранятся указатели на объекты дочерних классов (разумеется при этом список объявлен как список указателей родительского класса)Добавлено (05.11.2010, 09:22) --------------------------------------------- так должен выглядеть код: CrossIter=Obj_List.begin(); CObject* pObject; CBullet *pBullet; while(CrossIter!=Obj_List.end()) { pObject=*CrossIter; if (pObject->type=="bullet") { if (CheckColl(cbox, pObject->cbox)==true) { pBullet=( CBullet*)pObject; //то же самое что я писал раньше только чуть более развёрнуто armor-=pBullet->damage; // Вот тут надо получаем доступ как к CBullet, а не CObject pObject->kill=true; } } CrossIter++; }
|
|
| |
ezhickovich | Дата: Пятница, 05 Ноября 2010, 09:28 | Сообщение # 11 |
[Великий и могучий хозяинъ]
Сейчас нет на сайте
| Нужно поставить ещё одни скобки... Иначе получается, что приводим неопределённую переменную damage к типу CBullet* - FAIL Чуть исправил: Code #include <cstdio>
class A {}; class B : public A { public: int foo; };
int main () { A *a = new B; ((B*)a)->foo = 10; int foo = ((B*)a)->foo; printf ("%d", foo); return 0; } На экран должно быть выведено "10"
Я: О великий повелитель этой ничтожной вселенной - сокращённо ЁЖ!
|
|
| |
Faeton | Дата: Пятница, 05 Ноября 2010, 10:48 | Сообщение # 12 |
частый гость
Сейчас нет на сайте
| скобки не проверял)))(просто скопировал код и вставил свои строки) Целью видел показать пример использования механизма приведения типов указателей
|
|
| |
ezhickovich | Дата: Пятница, 05 Ноября 2010, 10:53 | Сообщение # 13 |
[Великий и могучий хозяинъ]
Сейчас нет на сайте
| Quote (Faeton) armor-=( CBullet*)pObject->damage; Просто этот код не может компилиться =) А если поставить всего две скобки, то всё ок... P.S. Откуда код взял?
Я: О великий повелитель этой ничтожной вселенной - сокращённо ЁЖ!
|
|
| |
Faeton | Дата: Пятница, 05 Ноября 2010, 11:12 | Сообщение # 14 |
частый гость
Сейчас нет на сайте
| Понял))))действительно, забыл скобки. Внутренние скобки нужны для указания в какой тип привести, а внешние указывают, что привести. код Renus, я просто вставил свои строки, для наглядности. А вообще armor-=(( CBullet*)pObject)->damage;// даёт доступ к свойству CBullet в данный "момент" кодаДобавлено (05.11.2010, 11:12) --------------------------------------------- альтернатива приведению указателей так называемое "позднее связывание методов" посредством virtual
|
|
| |
ezhickovich | Дата: Пятница, 05 Ноября 2010, 11:25 | Сообщение # 15 |
[Великий и могучий хозяинъ]
Сейчас нет на сайте
| В данном случае мы имеем дело с переменной => virtual не катит...
Я: О великий повелитель этой ничтожной вселенной - сокращённо ЁЖ!
|
|
| |
Renus | Дата: Пятница, 05 Ноября 2010, 11:35 | Сообщение # 16 |
почетный гость
Сейчас нет на сайте
| О! Заработало!!!! Спасибо ребят, даю плюс в репы))) НА выходных постараюсь выложить новую версию своей игрушки, а через недельку возможно версию для тестов, так заходите и смотрите)
|
|
| |
Faeton | Дата: Пятница, 05 Ноября 2010, 12:24 | Сообщение # 17 |
частый гость
Сейчас нет на сайте
| В данном случае мы имеем дело с переменной => virtual не катит... Вообще то доступ к переменным грамотно делать посредством методов. А все поля должны быть private или protected. И тогда в силу всупает необходимость virtual методов в родительском классе. Это называется хорошим стилем. В результате легко манипулировать сложными классами образуемые наследованием. Поэтому и смог закончить сложные проекты)))
|
|
| |
ezhickovich | Дата: Пятница, 05 Ноября 2010, 12:45 | Сообщение # 18 |
[Великий и могучий хозяинъ]
Сейчас нет на сайте
| Тем не менее у автора не такая реализация... => virtual всёравно не катит ... Хотя он может её переписать...
Я: О великий повелитель этой ничтожной вселенной - сокращённо ЁЖ!
|
|
| |
Faeton | Дата: Пятница, 05 Ноября 2010, 13:16 | Сообщение # 19 |
частый гость
Сейчас нет на сайте
| ))))))))))) А я между прочим писал: В случае если объявленный указатель на некоторый класс, ссылается на объект дочернего класса, доступ к его методу можно получить лишь таким способом в другом посте ниже альтернатива приведению указателей так называемое "позднее связывание методов" посредством virtual ещё ниже Вообще то доступ к переменным грамотно делать посредством методов. А все поля должны быть private или protected. И тогда в силу всупает необходимость virtual методов в родительском классе. Это называется хорошим стилем. В результате легко манипулировать сложными классами образуемые наследованием. Поэтому и смог закончить сложные проекты))) Вот вам)))))))) Короче дал понять в последнем посте, что реализовать можно грамотней и показал с помощью чего)))
|
|
| |
Renus | Дата: Пятница, 05 Ноября 2010, 16:09 | Сообщение # 20 |
почетный гость
Сейчас нет на сайте
| Ну для этого проекта оставим так, он все таки первый... А вообще virtual у меня используется очень даже сильно, собсно у каждого объекта есть функции Process и Render которые виртуальные и у имеют свою реализацию для каждого класса...
|
|
| |