c++ - 在一个循环中对 2 个 vector 进行操作的问题

标签 c++ vector sfml

当我使用这个循环时,代码不能正常工作:

for(int i = 0; i < INTRO_LOGO_COUNT; i++)
{
    char path_buffer[32]; // 32 = logo_xxx.png
    sprintf(path_buffer, "data/texture/intro/logo_%d.png", i);
    std::cout << path_buffer;

    m_vecTextures.push_back(sf::Texture());
    m_vecTextures.back().loadFromFile(path_buffer);

    m_vecSprites.push_back(sf::Sprite());
    m_vecSprites.back().setTexture(m_vecTextures[i]);

    // Center
    m_vecSprites.back().setPosition(
        SCREEN_WIDTH / 2 - m_vecSprites.back().getLocalBounds().width / 2,
        SCREEN_HEIGHT / 2 - m_vecSprites.back().getLocalBounds().height / 2);
    m_vecSprites.back().setColor(sf::Color(255, 255, 255, 0)); // Opacity : 100%
}

纹理混合在一起,只有第二个纹理可以正常工作。 (INTRO_LOGO_COUNT 定义为 2) 第一个纹理具有有效尺寸,但图像来自第二个纹理。 第二个纹理具有有效的大小和图像。 但是经过 1 次更改(分为 2 个循环):

for( int i = 0; i < INTRO_LOGO_COUNT; i++ )
{
    char path_buffer[32]; // 32 = logo_xxx.png
    sprintf(path_buffer, "data/texture/intro/logo_%d.png", i);
    std::cout << path_buffer;

    m_vecTextures.push_back(sf::Texture());
    m_vecTextures.back().loadFromFile(path_buffer);
}

for( int i = 0; i < INTRO_LOGO_COUNT; i++ )
{
    m_vecSprites.push_back(sf::Sprite());
    m_vecSprites.back().setTexture(m_vecTextures[i]);
    // Center
    m_vecSprites.back().setPosition(
        SCREEN_WIDTH / 2 - m_vecSprites.back().getLocalBounds().width / 2,
        SCREEN_HEIGHT / 2 - m_vecSprites.back().getLocalBounds().height / 2);
    m_vecSprites.back().setColor(sf::Color(255, 255, 255, 0)); // Opacity : 100%
}

一切正常。 问题在哪里?我尝试了不同的方法,但效果总是一样的。 谢谢!

最佳答案

原因来自vector的实现。当一个vector被创建时,它会分配一个固定大小的内存,例如vector的初始大小是A。当你将元素压入vector并且大小达到A时,vector会自动重新分配另一个连续的大小为2*A的内存块,如果无法在同一地址重新分配大小为2*A的内存块,则会分配一个新的内存块,并将旧内存中的内容复制到新内存中。

所以在你的第一个循环中:

m_vecSprites.back().setTexture(m_vecTextures[i]);

根据您提供的链接,函数“setTexture”的定义是:

void Sprite::setTexture(const Texture& texture, bool resetRect)
{
    // Recompute the texture area if requested, or if there was no valid texture & rect before
    if (resetRect || (!m_texture && (m_textureRect == sf::IntRect())))
        setTextureRect(IntRect(0, 0, texture.getSize().x, texture.getSize().y));

    // Assign the new texture
    m_texture = &texture;
}

并且成员变量'm_texture'是指针类型

函数 'setTexture' 获得了对 m_vecTextures[i] 的引用,但是由于 vector 'm_vecTextures' 仍然会增加,如果它达到初始大小, vector 将调整大小并移动内存块,并且引用可能变为有效。

如果 vector 初始化大小为 INTRO_LOGO_COUNT,第一个循环将正常工作。

关于c++ - 在一个循环中对 2 个 vector 进行操作的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22947189/

相关文章:

c++ - 链接 netpbm 库时出现问题

c++ - openGL子纹理

c++ - 通过类引用访问和改变 vector

c++ - std::list 和 std::vector - 两全其美?

c++ - 无法使用 C++ 和 SFML 2.1 将图像文件加载为纹理

c++ - 对于解析器来说,上下文无关文法的这种表示有多好?

c++ - 如何在 C++ 中创建缓冲区以创建新文件

c++ - 从迭代器返回对象的引用

c++ - 使用库中的抽象类时如何解决 "deep copy of an abstract class"问题?

c# - NLayer MpegFile到SFML.Net SoundStream