我有一个带有几个继承者的抽象基类,我创建了一个指向继承者的抽象基类指针数组:
抽象基类:
class Tile
{
public:
bool isPassable;
void setTileSet( SDL_Texture *Texture );
SDL_Rect* clip;
};
继承人:
class Floor: public Tile
{
public:
bool isPassable = true;
SDL_Rect clip = { 20, 0, 20, 20 };
};
指针数组:
Tile * dungeon[ z ][ x ][ y ] = {{{ nullptr }}};
当我尝试通过指针数组访问成员 SDL_Rect 剪辑以 blit block 时,没有任何反应。程序编译运行,但屏幕保持默认黑色:
dungeon[ 0 ][ 0 ][ 0 ] = &floor;
Draw::renderTexture( TILESET, REN, 0, 0, dungeon[ 0 ][ 0 ][ 0 ]->clip );
但是,当我只使用类 Floor 访问剪辑时,图像会正常传输:
Draw::renderTexture( TILESET, REN, 0, 0, floor.clip );
我以为指针抽象基类可能一直没有加载,但是当我试图写出代码来清除它时:
SDL_Rect error = { 0, 0, 20, 20 };
if( dungeon[ 0 ][ 0 ][ 0 ] != nullptr )
{
Draw::renderTexture( TILESET, REN, 0, 0, dungeon[ 0 ][ 0 ][ 0 ]->clip );
}
else
{
Draw::renderTexture( TILESET, REN, 0, 0, &error );
}
屏幕保持黑色。
这是 Draw::renderTexture 函数,虽然我怀疑这是问题所在:
void Draw::renderTexture(SDL_Texture *texture, SDL_Renderer *render, int x, int y, SDL_Rect *clipping )
{
SDL_Rect destination;
destination.x = x;
destination.y = y;
destination.w = clipping->w;
destination.h = clipping->h;
SDL_RenderCopy( render, texture, clipping, &destination );
最佳答案
在每一层,你有两个版本的 isPassable:Floor::isPassable
和 Tile::isPassable
。一个已初始化,另一个未初始化。您还有两个版本的剪辑。 Floor::clip
未初始化,Tile::clip
未初始化。因此,当您将地牢元素称为 Tile 时,很自然地,它会访问未初始化的元素并引发灾难。
你的代码说 if( dungeon[ 0 ][ 0 ][ 0 ] != nullptr )...
没有帮助,因为 Tile::clip
不为空;它未初始化。
解决方案是从 Tile 或 Floor 中删除 isPassable 和 clip,这样您将只有一个拷贝,并且不会访问错误的拷贝。
如果您想将其保留在 Tile 中,需要解决以下问题:
- 在 Tile 的构造函数中初始化它们,可能默认为 false 和 NULL——所有类的所有成员都需要初始化。这就是为什么您的 if 语句没有帮助
- 如果 Floors 需要不同的初始值,则让 Floor 的 ctor 调用 Tile 的 ctor,传递适当的值:
Floor () : Tile (true, 20, 0, 20, 20) {}
,也许。
关于c++ - 使用抽象基类指向 SDL_Rect 类成员的指针问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25413792/