SFML纹理持有人已删除,但仍在范围内

时间:2019-06-13 14:39:40

标签: c++ oop sfml

所以我是SFML的新手。我读了很多文章,但我确实听不懂。 我写了一个纹理支架:

class tile_texture_holder {
private:
    sf::Texture tx;
public:
    tile_texture_holder(type a) {
        switch (a) {
        case type::desert:
            tx.loadFromFile("C:/Users/Andreas/source/repos/conquer/Media/desert.png");
            break;
        case type::grass:
            tx.loadFromFile("C:/Users/Andreas/source/repos/conquer/Media/grass.png");
            break;
        case type::mountain:
            tx.loadFromFile("C:/Users/Andreas/source/repos/conquer/Media/mountain.png");
            break;
        case type::water:
            tx.loadFromFile("C:/Users/Andreas/source/repos/conquer/Media/water.png");
            break;
        }
    }
    sf::Texture ret_texture() {
        return tx;
    }

    ~tile_texture_holder() {
        std::cout << "///////////////////////HOLDER DELETED!!!/////////////////////" << std::endl;
    }
};

然后我尝试用不同的方式加载精灵。...

例如:

tile_texture_holder t(type::desert);
        sf::Sprite s; 
        s.setTexture(t.ret_texture());

(在同一函数中,我绘制精灵)

我总是会画出白框。而且我真的不明白为什么texture_holder被删除。

BTW类型是一个枚举。

我希望有人能帮助我解决我的问题!

1 个答案:

答案 0 :(得分:1)

s.setTexture(t.ret_texture());
在上面的行中,

您的行为不确定。

ret_texture返回临时纹理(按值返回,因此将进行复制),setTexture对其进行引用,然后在表达式末尾销毁临时纹理,并且您有悬挂的引用在s中。

为什么会这样?由于setTexture中的Sprite仅保留对纹理的引用,因此不会复制它。

根据SFML Sprite reference

  

纹理参数是指必须存在的纹理   精灵使用它。实际上,该精灵不会存储自己的副本   纹理,而是保持指向您传递给的纹理的指针   此功能。

解决方案:ret_texture应该通过引用返回纹理。

sf::Texture& ret_texture() {
    return tx;
}