sf :: String член класса возвращается к пустому - PullRequest
1 голос
/ 24 января 2012

Эти строки кода выполняются:

Enemy* enemy = new Enemy(m_pSceneManager,"enemy"+ss.str());
std::cout << "Enemy name = " << std::string(enemy->name) << std::endl;
Add(enemy->name,enemy);

в EnemyManager.cpp.EnemyManager наследует от GameObjectManager:

void GameObjectManager::Add(sf::String name,VisibleGameObject* obj){
    std::cout << "GameObjectManager obj name = " << std::string(obj->name) << std::endl;
    gameObjects.insert(std::pair<sf::String,VisibleGameObject*>(name,obj));
}

Enemy наследует от VisibleGameObject, у которых есть открытая переменная sf :: String 'name', но только Enemy инициализирует ее в любой точке (в своем конструкторе).Вывод в окне консоли таков:

Enemy name = enemy0
GameObjectManager obj name = 

Почему name возвращается к нулю?Я предполагаю, что это как-то связано с тем фактом, что аргумент является VisibleGameObject *, а не Enemy * - если это так, как я могу обойти это?Если я допустил ошибку где-то еще, пожалуйста, сообщите мне, если какие-либо детали, которые мне не хватает, требуются.

Спасибо

Ответы [ 2 ]

2 голосов
/ 24 января 2012

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

struct VisibleGameObject {
    sf::String name;
};

struct Enemy : VisibleGameObject {
    Enemy(SceneManager*, sf::String newName) : VisibleGameObject(), name(newName)
    sf::String name;
};

struct GameObjectManager {
    void GameObjectManager::Add(sf::String name,VisibleGameObject* obj){
        std::cout << "GameObjectManager obj name = " << std::string(obj->name) << std::endl;
        gameObjects.insert(std::pair<sf::String,VisibleGameObject*>(name,obj));
    }
private:
    std::map<sf::String, VisibleGameObject*> gameObjects;
};

struct EnemyManager : GameObjectManager {
    void foo() {
        //This code probably leads to a memory leak, but you might have solved it in some
        //way that you are not showing.
        Enemy* enemy = new Enemy(m_pSceneManager,"enemy"+ss.str());
        std::cout << "Enemy name = " << std::string(enemy->name) << std::endl;
        Add(enemy->name,enemy);
    }
};

Что это означает - когда создается объект Enemy, переменная Enemy::name инициализируется для хранения "enemy"+ss.str(). Однако переменная VisibleGameObject::name (которая находится в части VisibleGameObject Enemy) инициализируется для хранения значения по умолчанию (в котором нет текста).

В EnemyManager::foo переменная имени, на которую ссылается, - это переменная в Enemy. В GameObjectManager::Add переменная name, на которую ссылаются, является переменной в VisibleGameObject базовом члене Enemy. VisibleGameObject::name по-прежнему имеет значение по умолчанию, поэтому ничего не печатается.

1 голос
/ 24 января 2012

Поскольку, как вы говорите, оба имеют открытую переменную sf :: String 'name', но только Enemy инициализирует ее в любой точке (в своем конструкторе). , существует два name подобъекта: один является членом Enemy, а другой является подобъектом VisibleGameObject. Внутри функции Add вы явно ссылаетесь на последнюю, так что это то, что вы получаете, и она не инициализируется.

Возможно, вы захотите сделать name виртуальной функцией, возвращающей строку; это заставит функцию Add использовать полиморфизм времени выполнения и вызвать name() из производного класса, то есть из Enemy.

Более простой (но не обязательно лучший) дизайн - сделать name защищенным или открытым членом VisibleGameObject и позволить Enemy установить его; это также означает, что вы, скорее всего, захотите удалить name из Enemy, в противном случае name, унаследованное от VisibleGameObject, будет скрыто.

...