Можно ли как-то в c++ узнать принадлежность объекта классу?
У меня есть (пока нет но, прежде чем начать нужно определится с такими вещами) массив объектов игры. Это разные классы, которые наследуют от одного (Object, например). То есть все они являются Object.
Но как мне понимать, что элемент этого массива является не только Object в общем, но и, например, игроком или врагом или стеной или еще чем-то?
В js я бы написал:
if (objects[i] instanceof Wall) { ... }
Но как такое сделать с С++? При этом без костылей.
Или может быть я не правильно понимаю как такие вещи делаются в С++? Если да, но как это организовывают?
Зачем вам это? Есть полиморфизм, а касты -- это плохой стиль почти всегда.
Можно много чего использовать, в том числе и тэги. В базовом классе создаёте перечисление, где каждый элемент -- тип наследника + 1 элемент на тип базового класса. В базовом классе определяете виртуальный метод вроде type() и реализуете его для всех наследников.
Но перед тем, как сделать это, хорошо подумайте над тем, надо ли оно вам. Про SOLID почитайте, в особенности про букву L.
Почитайте например вот это: https://stackoverflow.com/questions/1986418/typeid...
особенно ответ.
Где то видел еще реализацию через темплейты.
Но 90% что чт то не так с архитектурой раз такое надо. И если уж надо и наследуетесь от базового класса - то сделайте в базовом классе метод, который вернет тип по enum.
Согласен, что архитектура, скорее всего не правильная. Но какой она должна быть? Как это правильно организовывать?
ООП, по-идеи, должно абстрагировать реальный мир.
И если, например, я герой игры и передо мной находится какой-то персонаж, то я должен как-то понимать кто это - враг, союзник или просто какой-то житель. Но как это реализовать?
Дима Гашко, спросить у этого объекта - ты враг? Тобишь bool IsEnemy();
Или спросить его тип как вы и описали, но через енам, а не опускаться до типов данных.
Объясню почему на вашем же примере про врагов и союзников.
У вас может быть класс EnemyArcher, EnemyFighter и EnemyBoss. Все они - враги.
И есть метод (дай бог что один), который проверяет враг ли перед нами сравнивая тип данных с вот этими вот тремя классами.
Потом внезапно вы заводите EnemySorcerer. Вам надо не забыть его прописать в методе определения врагов, и - что самое важное - код вам об этом не напоминает! А если у вас все наследуется от BaseObject, у которого есть абстрактный метод IsEnemy (ну или getType(), возвращающий енам) - то вы не забудете его реализовать - иначе просто не скомпилится.
И если, например, я герой игры и передо мной находится какой-то персонаж, то я должен как-то понимать кто это - враг, союзник или просто какой-то житель. Но как это реализовать?
ээм
кажется у вас что-то с ооп.
Враг, союзник или житель это роли, которые описывают отношение к игроку.
Иными словами, их "враждебность" или "дружественность" зависит исключительно от поведения, а виды поведений это уже совершенно другой объект.
подумайте в сторону setBehavior(FriendlyBehaviorObject);
GavriKos, Спасибо. В общем, понял. Вариант в стиле IsEnemy получается как раз то что нужно.
Правда не совсем понятно про enum, можете подробнее описать, или привести какой-то очень упрощенный псевдо код?
GavriKos, Я понял.
Правда в таком виде оно подходит под то что я описывал, но не совсем.
Я там хотел иметь возможность в одном месте проверить является ли объект, врагом, в другом, является ли он живым объектом.
Аналогия с реальной жизнью: видя, например, разработчика, я понимаю, что он не только разработчик, но и IT-шник, человек, и зная, что он разработчик, могу предложить ему проект, зная что человек - попросить помощи.
Но все же для моей задачи скорее всего достаточно будет IsEnemy.