sf::类的字符串成员恢复为空

sf::String member of class reverts to blank

本文关键字:恢复 成员 字符串 sf      更新时间:2023-10-16

运行以下代码行:

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中。EnemyMManager继承自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*这一事实有关——如果是,我该如何解决这一问题?如果我在其他地方犯了错误,请告诉我是否需要我遗漏的任何细节。

感谢

如果我正确理解您的描述,您的代码如下所示:

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变量(位于Enemy的VisibleGameObject部分)被初始化为保持其默认值(其中不包含文本)。

EnemyManager::foo中,引用的名称变量是Enemy中的名称变量。在GameObjectManager::Add中,引用的name变量是EnemyVisibleGameObject基成员中的变量。VisibleGameObject::name仍然有其默认值,因此不会打印任何内容。

因为,正如您所说,都有一个公共的sf::String'name'变量,但只有Enemy在任何时候(在其构造函数中)初始化它,有两个子对象name:一个是Enemy的成员,另一个子对象是VisibleGameObject的子对象。在函数Add中,您明确地引用了后一个,所以这就是您得到的,并且它没有初始化。

您可能想要使name成为一个返回字符串的虚拟函数;这将使函数Add采用运行时多态性并从派生类(即从Enemy)调用name()

更简单(但不一定更好)的设计是使name受保护或成为VisibleGameObject的公共成员,并让Enemy设置它;这也意味着您很可能希望从Enemy中删除name,否则从VisibleGameObject继承的name将被隐藏。