c++是如何将事物保持在范围内的?

How does c++ keep things in scope?

本文关键字:范围内 c++      更新时间:2023-10-16

更具体地说,我有一个看起来像这样的类:

class Ball {
    public:
        unsigned collider_size;
        scionofbytes::MovementComponent movement;
        scionofbytes::GraphicComponent graphic;
        Ball(u_int init_collider_size, std::string texture_path) {
            collider_size = init_collider_size;
            movement = scionofbytes::MovementComponent();
            graphic = scionofbytes::GraphicComponent(
                    (u_int) collider_size/2,
                    (u_int) collider_size/2,
                    texture_path
            );
        }
};

我接受texture_path并将其传递给图形组件,看起来像这样:

class GraphicComponent {
    unsigned height;
    unsigned width;
    public:
        sf::Texture texture;
        sf::Sprite sprite;
        GraphicComponent() {}
        GraphicComponent(unsigned init_height, unsigned init_width, std::string texture_path) {
            width = init_width;
            height = init_height;
            texture.loadFromFile(texture_path);
            sprite.setTexture(texture);
        }
};

当我通过传递texture_path实例化一个球对象时,我正在创建一个纹理作为图形组件的成员,然后将该纹理分配给图形组件的sprite成员。

当使用这个精灵成员绘制到屏幕上时,我面临着SFML已知的白框问题

现在从我的理解来看,球对象保持活跃,图形组件成员也保持活跃,图形组件的纹理成员也是如此。

所以我的问题是,为什么这不起作用?当使用精灵在屏幕上作画时,我仍然会看到一个白色的盒子。为什么纹理会被破坏?

在您的Ball类构造函数中,您正在制作GraphicComponent副本。IIRC sf::Sprite仅保存对sf::Texture的引用,因此您的副本可能最终以sf::Sptite指向从其复制的对象中删除的sf::Texture告终。

试着构造你的Ball ,而不复制你的GraphicComponent:

class Ball {
    public:
        unsigned collider_size;
        scionofbytes::MovementComponent movement;
        scionofbytes::GraphicComponent graphic;
        // Use initializer-list
        Ball(u_int init_collider_size, std::string texture_path)
        : collider_size(init_collider_size)
        , movement()
        , graphic((u_int) collider_size/2, (u_int) collider_size/2, texture_path)
        {
             // don't assign stuff here if you can avoid it
        }
};

除了,你可能还想为你的GraphicComponent类创建一个复制构造函数,以防止其他地方的损坏:

class GraphicComponent
{
    unsigned height;
    unsigned width;
public:
    sf::Texture texture;
    sf::Sprite sprite;
    GraphicComponent()
    {
    }
    GraphicComponent(unsigned init_height, unsigned init_width,
        std::string texture_path)
    {
        width = init_width;
        height = init_height;
        texture.loadFromFile(texture_path);
        sprite.setTexture(texture);
    }
    // Give it a copy constructor
    GraphicComponent(GraphicComponent const& other)
    : height(other.height)
    , width(other.width)
    , texture(other.texture)
    , sprite(texture) // make it point to the new Texture not the other one
    {
    }
};