问题描述
我对指向变量的指针行为背后的推理感到非常困惑。我会想,如果我附加一个指向 vector
的指针并访问它,无论我改变了指针本身,它仍然应该在同一个变量上工作。我的意思是,例如,我有一个整数指针向量,我修改了一个在其他地方定义的变量,该变量已附加到该向量。如果我要打印它们,它应该更新向量(实际上不是),但它应该打印一个整数的新值。我正在尝试将其应用于 SDL2 中的 SDL_Texture*
,但这并不完全合理。总之,同样的概念在那里应用,但我使用的是纹理。我修改了纹理并用它做“事情”,但是在我渲染它的循环结束时,向量仍然迭代到附加到它的 SDL_Texture*
无论如何。我的问题是,当我改变和修改纹理时,当我去渲染它时它没有出现。这不是因为纹理没有正确加载或任何东西(我已经测试过它,而不是使用矢量,我绘制它原始)但是当使用矢量时它不能正常工作。代码如下:
void Main::Mainloop()
{
Screen_Object m_Screen_Object;
TTF_Font* font = TTF_OpenFont("Anonymous_Pro.ttf",30);
SDL_Surface* surf = TTF_RenderText_Blended(font,"Starting fps",{0,0});
SDL_Texture* tex = SDL_CreateTextureFromSurface(Render::Get_Renderer(),surf);
SDL_FreeSurface(surf);
SDL_Rect rct = {20,100,0};
SDL_QueryTexture(tex,NULL,&rct.w,&rct.h);
m_Screen_Object.Add_Texture(tex);
Uint32 start,finish,counter;
counter = 0;
start = SDL_GetTicks();
finish = SDL_GetTicks();
bool running = true;
while (running)
{
Events::Event_Loop();
if (Events::Quit_Application()){
running = false;
break;
}
///Clear display to color
SDL_SetRenderDrawColor(Render::Get_Renderer(),255,255);
SDL_RenderClear(Render::Get_Renderer());
///Do stuff here
m_Screen_Object.Draw_Textures();
finish = SDL_GetTicks();
counter += 2;
if (finish - start >= 500)
{
start = SDL_GetTicks();
SDL_DestroyTexture(tex);
std::string fps = std::to_string(counter);
surf = TTF_RenderText_Blended(font,fps.c_str(),0});
tex = SDL_CreateTextureFromSurface(Render::Get_Renderer(),surf);
SDL_FreeSurface(surf);
SDL_QueryTexture(tex,&rct.h);
counter = 0;
}
SDL_RenderPresent(Render::Get_Renderer());
}
SDL_DestroyTexture(tex);
TTF_CloseFont(font);
}
int main(int argc,char* argv[])
{
Main::Mainloop();
return 0;
}
这里是 Screen_Object
的声明:
在标题中:
std::vector < SDL_Texture* > m_Textures;
在 .cpp 中:
void Screen_Object::Add_Texture(SDL_Texture* p_Texture)
{
m_Textures.push_back(p_Texture);
}
void Screen_Object::Draw_Textures()
{
for (unsigned int i=0; i < m_Textures.size(); i++)
{
SDL_Rendercopy(Render::Get_Renderer(),m_Textures[i],&m_Rect);
}
}
现在这段代码没有按照我认为应该的方式工作,因为我不明白为什么它不工作,但是当我将向量的类型更改为 SDL_Texture**
时,代码工作正常。没有 **
的代码到底有什么问题,我无法从逻辑上理解为什么它不能正常工作
解决方法
问题似乎是您将指针存储在向量中,但在向量之外使指针无效。
void Screen_Object::Add_Texture(SDL_Texture* p_Texture)
{
m_Textures.push_back(p_Texture);
}
void Main::Mainloop()
{
Screen_Object m_Screen_Object;
//...
SDL_Texture* tex = SDL_CreateTextureFromSurface(Render::Get_Renderer(),surf);
//...
m_Screen_Object.Add_Texture(tex); // <-- add pointer to vector
//...
tex = SDL_CreateTextureFromSurface(Render::Get_Renderer(),surf); // <-- This changes the pointer,but has no effect on the vector's
//...
所以在该行之后的任何内容,如果您访问 m_Textures
向量中的指针,向量中的指针不再有效,或者更糟的是,它有效,但指向旧的(但仍然有效){ {1}}。
一个非常简单的解决方案是通过获取对该指针的引用来确保您使用存储在 SDL_Texture
中的指针:
m_Textures
然后在此之后使用 void Main::Mainloop()
{
Screen_Object m_Screen_Object;
TTF_Font* font = TTF_OpenFont("Anonymous_Pro.ttf",30);
SDL_Surface* surf = TTF_RenderText_Blended(font,"Starting fps",{0,0});
SDL_Texture* tex = SDL_CreateTextureFromSurface(Render::Get_Renderer(),surf);
m_Screen_Object.Add_Texture(tex); // <-- Immediately do this
auto& texRef = m_Screen_Object.back(); // <-- Get a reference to the pointer.
。这是对添加到向量的指针的实际引用,而不是指针的副本。
那么循环将很简单:
texRef
这会改变存储在向量中的实际指针。