了解如何使用SFML函数将数据添加到地图

时间:2017-01-10 00:06:42

标签: c++ dictionary sfml

我正在使用SFML和c ++ 11进行这个简单的教程。我正在教授地图容器。我有c#知识,我的理解是地图与字典相同。我的问题是他提供的代码片段,但不能很好地解释。

TextureHolder.h

std::map<std::string, sf::Texture> m_textures;

TextureHolder.cpp

sf::Texture& TextureHolder::GetTexture(std::string const& filename)
{
    auto& r_textures = m_s_instance -> m_textures;
    auto keyValuePair = r_textures.find(filename);

    if (keyValuePair != r_textures.end())
    {
        return keyValuePair->second;
    }
    else
    {
        auto& texture = r_textures[filename];
        texture.loadFromFile(filename);
        return texture;
    }
}

我理解除了else语句之外的所有内容。这是我对最新情况的理解,但是如果有人能向我澄清实际发生了什么以及为什么我错了,我会很感激。

auto& texture = r_textures[filename]这将使用filename的密钥创建一个新的键值对。然后它将值赋给纹理,这是一个空值,因为没有加载纹理。

texture.loadFromFile(filename);这会加载纹理文件并将其指定给纹理。这是我完全迷失的地方。这条线的某种方式也是将纹理添加到键的值。

然后它将纹理返回给调用函数。

这可能更多地是对SFML如何处理纹理对象的误解,但我仍然对这条线如何与地图中的键值对进行通信感到困惑。

4 个答案:

答案 0 :(得分:4)

  

自动&安培; texture = r_textures [filename]这将创建一个新的键值对   用文件名的键。然后它将值赋给纹理,其中   是一个空值,因为没有加载纹理。

不完全正确。 texture是一个参考。它本身并不是一个谨慎的对象。

这将创建一个新的键/值对,并在地图中设置引用texture以引用新创建的值。

后续loadFromFile()通过loadFromFile()引用调用texture方法。这恰好引用了地图中新插入的值。

然后,返回对从文件中新加载的值的引用。

胶囊摘要:它搜索地图以查看是否找到了密钥,如果是,则返回对密钥值的引用。否则,它会为该键创建一个新的键/值对,初始化新值,然后返回它。

答案 1 :(得分:3)

  

auto& texture = r_textures[filename]这将使用filename的密钥创建一个新的键值对。然后它将值赋给纹理,这是一个空值,因为没有加载纹理。

它不会将分配给texture。它使texture成为对新创建的纹理的引用。这就是&中的auto&所做的。

  

texture.loadFromFile(filename);这会加载纹理文件并将其指定给纹理。这是我完全迷失的地方。这条线的某种方式也是将纹理添加到键的值。

它不会将其分配给texture,而是将其分配给texture引用的对象 - 请记住,texture是参考。它指的是地图中的纹理。

  

然后它将纹理返回给调用函数。

实际上,它会返回对它的引用。请记住,返回类型为sf::Texture&

答案 2 :(得分:2)

在本声明中

auto& texture = r_textures[filename];

在地图中创建了一个新对,其键等于filename,映射值等于通过调用默认构造函数sf::Texture()创建的对象。并且运算符返回对创建的映射值的引用。此引用存储在变量texture中,而变量texture.loadFromFile(filename); 又是引用。因此,此引用引用映射类型的原始默认创建对象。

然后更新存储在地图中的映射类型的原始对象

texture

因为变量return texture; 是对象的引用。

最后,从函数

返回此引用,该引用是对地图中原始映射对象的引用
operator []

因此StringCaseSense, on StringGetPos, OutputVar, Clipboard, book msgbox, %OutputVar% 或者返回对映射对象的引用,如果对应于指定键的对象已经存在于映射中,或者创建一个新的映射对象,调用其默认构造函数并返回对该映射对象的引用。新创建的映射对象。

答案 3 :(得分:1)

其他答案解释了您发布的代码。

但是,正如我的评论建议的那样,使用std::map::insert()代替find()然后使用[]可能会使代码更清晰。诀窍是知道std::map::insert返回什么以及如何使用它。

sf::Texture& TextureHolder::GetTexture(std::string const& filename)
{
    auto& r_textures = m_s_instance -> m_textures;

    // potentially insert a new texture.  If not inserted, then the 
    // current one remains in the map
    auto ret = r_textures.insert(std::make_pair(filename, sf::Texture()));

    // ret is a std::pair<map::iterator, bool>, where map::iterator is 
    // the iterator to the existing or newly inserted item.  The second
    // is a bool that is either true or false, depending on whether new item
    // was inserted or not.

    // Now get the texture.  A map's iterator is itself a pair, so 
    // 'first' of this pair is the filename, and 'second' is the texture.
    auto& texture = ret.first->second;  

    // this tells us if it's a new item inserted
    if ( ret.second )  
       texture.loadFromFile(filename);

    return texture;   
}

这基本上与您的版本做同样的事情,只是它使用map::insert来确定是否插入了新项目并使用了insert的返回值。

请注意,map::insert需要std::pair由“潜在”新密钥和值组成(它是“潜在”,因为我们不知道是否会插入新密钥 - 我们使insert()决定)。

如果密钥已经存在,那么insert除了返回迭代器/布尔对之外什么都不做。如果密钥不存在,那么insert默认情况下会插入一个全新的sf::Texture构建一个(参见make_pair的第二个参数),然后返回迭代器/ bool对