运行以下代码行:
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 *而不是敌人*这一事实有关 - 如果是,我该如何解决这个问题呢?如果我在其他地方犯了错误,请告诉我是否有任何需要的细节。
由于
答案 0 :(得分:2)
如果我正确理解您的描述,您的代码如下所示:
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
变量是VisibleGameObject
Enemy
基本成员中的变量。 VisibleGameObject::name
仍有默认值,因此不会打印任何内容。
答案 1 :(得分:1)
因为,正如你所说都有一个公共的sf :: String'name'变量,但只有Enemy在任何时候(在它的构造函数中)初始化它。,有两个name
子对象:一个是Enemy
的成员,另一个是VisibleGameObject
的子对象。内部函数Add
你明确地引用了后者,所以这就是你得到的,并且没有初始化。
你可能想让name
一个虚函数返回字符串;这将使函数Add
使用运行时多态性并从派生类调用name()
,即从Enemy
。
更简单(但不一定更好)的设计是让name
受保护或VisibleGameObject
的公共成员,让Enemy
设置它;这也意味着您很可能希望从name
中移除Enemy
,否则将隐藏从name
继承的VisibleGameObject
。