gpt4 book ai didi

c++ - SDL Destructor 过早调用

转载 作者:太空宇宙 更新时间:2023-11-04 16:22:51 26 4
gpt4 key购买 nike

我正在用 SDL 编写基于图 block 的 map ,Map 类的构造函数用于设置用于表示包含的每个 MapCell 对象的图像在里面。但是,我的 Sprite 类的析构函数有问题,该类用于释放对象持有的 SDL_Surface*。析构函数被提前调用,我不完全确定为什么。这是我的 Map 构造函数的精简版本,仅显示单元格的 Sprite 是如何分配的。

Map::Map(string fileName, int tileWidth, int tileHeight)
{
string mapData = ReadMap(fileName);
_cells = new MapCell[_width*_height];

for(int y = 0; y < _height; y++)
{
for(int x = 0; x < _width; x++)
{
int currentCell = y*_width+x;

if(mapData[currentCell] == '0' || mapData[currentCell] == 'P' || mapData[currentCell] == 'X')
{
_cells[currentCell]._sprite = Sprite(Point2D(x*tileWidth, y*tileHeight), "Assets/Graphics/Grass.bmp");
if(mapData[currentCell] == 'P')
_cells[currentCell]._sprite = Sprite(Point2D(x*tileWidth, y*tileHeight), "Assets/Graphics/Player.bmp");
if (mapData[currentCell] == 'X')
_cells[currentCell]._sprite = Sprite(Point2D(x*tileWidth, y*tileHeight), "Assets/Graphics/Target.bmp");
}
else if(mapData[currentCell] == '1')
_cells[currentCell]._sprite = Sprite(Point2D(x*tileWidth, y*tileHeight), "Assets/Graphics/Wall.bmp");
}
}
}

析构函数似乎是在创建 Sprite 对象后立即调用的。我在这里错过了什么?我也试过在堆上分配 MapCell_sprite 成员,但它会导致同样的问题。据我所知,它不会超出范围,因为创建的 Sprite 对象是 Map 对象的一部分。

以下是我的Sprite 类的构造函数和析构函数:

Sprite::Sprite(void)
{
_texture = NULL;
_position = Point2D::Zero();
}

Sprite::Sprite(Point2D position, std::string texPath)
{
_texture = Content::LoadBMP(texPath);
_position = position;
}

Sprite::~Sprite(void)
{
SDL_FreeSurface(_texture);
}

如果有帮助的话,这是我的主要内容:

int main( int argc, char* args[] )
{
const int TILEWIDTH = 32;
const int TILEHEIGHT = 32;

// Initialization
InitSDL();
Map map = Map("Assets/Maps/Map3.txt", TILEWIDTH, TILEHEIGHT);
Window::SetSize(Rectangle(0, 0, map.GetWidth()*TILEWIDTH, map.GetHeight()*TILEHEIGHT));

PathFinder pathFinder = PathFinder();
List<Point2D> path = pathFinder.FindPath(map, map.GetPlayerStart(), map.GetTarget());
List<Sprite> PathNodes = List<Sprite>();
for(int i = 0; i < path.GetCount(); i++)
PathNodes.Add(Sprite(*path(i)*32, "Assets/Graphics/PathNode.bmp"));

bool quit = false;
SDL_Event Event;

while(quit == false)
{
while(SDL_PollEvent(&Event))
{
if(Event.type == SDL_QUIT)
quit = true;
}

map.Draw();

for(int i = 0; i < path.GetCount(); i++)
{
if(PathNodes(i)->GetPosition() != map.GetPlayerStart()*32 && PathNodes(i)->GetPosition() != map.GetTarget()*32)
PathNodes(i)->Blit();
}

Window::Flip();
}

//Quit SDL
SDL_Quit();

return 0;
}

最佳答案

问题是赋值x._sprite = Sprite(...)。这会创建一个 Sprite 临时对象,将其字段复制到 _sprite 中,然后销毁临时对象。此外,它不会在执行赋值之前调用 _sprite 上的析构函数,因此旧的 _texture 只会泄漏。

如果你想避免这种情况,请在 Sprite 上使用 .set.load 函数来更新 的内容Sprite 而不是复制,并创建私有(private) 赋值和复制构造方法以避免意外滥用。

关于c++ - SDL Destructor 过早调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15110623/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com