2017-01-17 20 views
0

У меня возникает проблема для получения правильного значения перечисления BaseClass.Значение параметра из класса Derivered, при использовании того же значения из базового класса

class BaseClass 
{ 
public: 
    enum EntityId { 
     EN_NONE = 0, 
     EN_PLAYER = 1, 
     EN_PLATFORM, 
     EN_GROUND, 
     EN_OBSTACLE, 
     EN_OTHER 
    }; 
    void setEntityId(EntityId id) { _Entityid = id; } 
    EntityId getEntityId() { return _Entityid; } 
protected: 
    EntityId _Entityid; 
}; 

и

Инициализация идет как этот

DeriveredClassA->setEntityId(BaseClass::EntityId::EN_PLAYER);

DeriveredClassB->setEntityId(BaseClass::EntityId::EN_OBSTACLE);

который помещается в другой список вектор correspoinding для этого перечисления.

Однако я вынужден использовать void* делать static_casts кошки ...

Как это:

BaseClass* EA = static_cast<BaseClass*>(bodyUserDataA); //bodyUserDataA and bodyUserDataB are both void* 
BaseClass* EB = static_cast<BaseClass*>(bodyUserDataB); 

И я пытаюсь получить с помощью EA->getEntityId() и EB->getEntityId(), чтобы я мог проверить, какой из них EN_PLAYER, который является EN_GROUND и т. Д. Таким образом, я мог бы повышать класс от базы до класса с высвобождением и делать с ним другие вещи.

Пробовал использовать с виртуальными, однако каким-то образом я получаю 2 копии _EntityID, которые могут быть либо одинаковыми, либо РАЗНЫМИ между моим Derivered и BaseClass этого одного объекта.

Кроме того, я не могу сразу перевести его в DeriveredClass, так как проверка кода будет огромной из-за множества разных типов DeriveredClass'es (DeriveredClassA, DeriveredClassB, DeriveredClassC, DeriveredClassD) с их соответствующим векторным списком.

Мой вопрос в том, что мне нужна правильная настройка как базового, так и деривативного класса, чтобы я мог получить доступ к _EntityID из Baseclass, который является тем же из этого DeriveredClass? Моя основная проблема может заключаться в том, что я использовал непрямо виртуальные функции, поэтому я оставил по умолчанию, чтобы понять мою проблему.

P.S. Это в основном моя проблема с C++, добавлены другие теги из-за того, что я использую движок игры и физический движок для этого случая.

+0

Возможно, вас заинтересует [dynamic_cast] (http://en.cppreference.com/w/cpp/language/dynamic_cast). Этот бросок предназначен для броска между типами, связанными с наследованием. –

+0

В том-то и дело, я не могу использовать dynamic_casts, дает мне ошибку «операнд указателя dynamic_cast должен быть указателем на полное имя класса» .... – Dinamix

+0

что такое 'EntityInfo'? Мы не знаем, как это связано с BaseClass или DerivedClassA/B. – RyanP

ответ

1

Я считаю, что вы хотите, чтобы ваш код выглядеть следующим образом:

class Entity 
{ 
public: 
    enum Type { 
     EN_NONE = 0, 
     EN_PLAYER = 1, 
     EN_PLATFORM, 
     EN_GROUND, 
     EN_OBSTACLE, 
     EN_OTHER 
    }; 

    Type getType() { return _type; } 

protected: 
    Entity(Type type): _type(type) {} 

private: 
    const Type _type; 
}; 

Тогда ваши производные классы и использование этой базы будет больше похож:

class PlayerEntity: public Entity, public SomeClass 
{ 
public: 
    PlayerEntity(std::string name): Entity(EN_PLAYER), _name(name) {} 
    std::string getName() const { return _name; } 

private: 
    std::string _name; 
}; 

class PlatformEntity: public Entity, public SomeClass 
{ 
public: 
    PlatformEntity(): Entity(EN_PLATFORM) {} 
}; 

Инициализация Затем выполняется как :

int main() 
{ 
    PlatformEntity platform; 
    std::vector<PlatformEntity> platforms(platform); 
    std::vector<PlayerEntity> players; 
    players.emplace_back("Bob"); 
    players.emplace_back("Alice"); 
    players.emplace_back("Ook"); 
} 

Доступ из пользовательских данных может выглядеть следующим образом:

// bodyUserDataA and bodyUserDataB are both void* 
Entity* const EA = static_cast<Entity*>(bodyUserDataA); 
Entity* const EB = static_cast<Entity*>(bodyUserDataB); 

switch (EA->getType()) 
{ 
    case Entity::EN_PLAYER: 
    { 
     PlayerEntity* player = static_cast<PlayerEntity*>(EA); 
     std::cout << "Found player: " << player->getName(); 
     break; 
    } 
    case Entity::EN_OTHER: 
     ... 
    default: 
     break; 
}