将指向多维数组向量中的单个项的指针传递给函数 c++
Passing pointer to single item in Vector of Multidimensional Array to Function c++
我正在使用 SDL 开发一个程序。我在主函数之外实例化了以下变量:
std::vector<SDL_Rect[TOTAL_ACTIVITIES][TOTAL_DIRECTIONS][ANIMATION_FRAMES]> gPersonSpriteClips;
(其中全大写项是常量整数(。这是一个数组的向量,因为我打算稍后做很多精灵开发。现在,我只有几个占位符精灵。因此,3D 数组捕获了单个人体类型精灵表的所有方面,当我拉入表时,我会让代码将其拆分为多种体型......
我有一个类"Character",它在准备渲染时利用数组。以下是在main中渲染myCharacter的调用:
myCharacter.render(bodySpritesheetTexture, &*gPersonSpriteClips[myCharacter.getBody()]);
Character.getBody(( 返回此字符实例使用的正文类型的向量索引。下面是 Character.h 中的函数声明:
void render(LTexture& characterSpriteSheetTexture, SDL_Rect spriteClips[TOTAL_ACTIVITIES][TOTAL_DIRECTIONS][ANIMATION_FRAMES]);
下面是 Character.cpp 中的函数本身:
void Character::render(LTexture& characterSpriteSheetTexture, SDL_Rect spriteClips[TOTAL_PERSON_ACTIVITIES][TOTAL_CARDINAL_DIRECTIONS][PERSON_ANIMATION_FRAMES])
{
characterSpriteSheetTexture.render( mPosition.x, mPosition.y, &spriteClips[mActivity][mDirection][mAnimations[mActivity][mCurrentFrame]] );
}
mActivity 是角色"当前正在执行的活动"的枚举。 mDirection是他面对的方向。 mAnimations 列出了帧顺序(因为其中一些动画以不同的顺序多次使用相同的精灵(。
最后,LTexture 的渲染函数直接取自 LazyFoo 的 SDL 教程。
characterSpriteSheetTexture.render(( 调用具有以下声明的函数(在 LTexture.h 中(:
void render( int x, int y, SDL_Rect* clip = NULL, int targetHeight = NULL, int targetWidth = NULL, double angle = 0.0, SDL_Point* center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE );
所以它期待一个 SDL_Rect* 剪辑类型的参数。该函数调用:
SDL_RenderCopyEx( gRenderer, mTexture, clip, &renderQuad, angle, center, flip );
编译代码时出现错误,将我指向 SDL 库中的某个位置。我已经成功地使用了 LTexture 的渲染函数,将索引从一维数组SDL_Rect传递到其中,所以我非常有信心这个问题存在于我的向量参数中。
忽略关于命名约定的分歧......我在这里做错了什么,实现我想要做的事情的正确方法是什么?
当然,我将来可能会大大简化我的动画方案;这是我第一次尝试生成玩家角色。无论如何,我想知道在这种情况下出错的机制。
最后,请不要建议我使用boost。我真的很想避免这个程序的提升。
伊塔:
以下是 Character.h 中 mAnimation 的声明:
std::vector<int> mAnimations[TOTAL_ACTIVITIES];
下面是它在默认构造函数中的初始化:
for (int i = 0; i < TOTAL_ACTIVITIES; i++)
{
mAnimations[i].resize(ANIMATION_FRAMES);
for (int j = 0; j < ANIMATION_FRAMES; j++)
{
mAnimations[i][j] = j;
}
}
像这样更改全局数组定义:
using SdlRectArray = std::array<std::array<std::array<SDL_Rect, ANIMATION_FRAMES>, TOTAL_DIRECTIONS>, TOTAL_ACTIVITIES>;
std::vector<SdlRectArray> gPersonSpriteClips;
请参阅此处,了解为什么不将数组存储在std::vector
或任何其他容器中。
因此,请按如下方式定义Character::render()
方法:
void render(LTexture& characterSpriteSheetTexture, SdlRectArray& spriteClips)
{
characterSpriteSheetTexture.render( mPosition.x, mPosition.y, &spriteClips[mActivity][mDirection][mAnimations[mActivity][mCurrentFrame]] );
}
然后你可以这样称呼它:
myCharacter.render(bodySpritesheetTexture, gPersonSpriteClips[myCharacter.getBody()]);
因为没有必要做&*
.
很难从您的问题中判断确切的错误是什么,但似乎根本原因可能是"数组衰减"。
在C++(和 C 中(中,数组参数几乎总是被视为指向数组开头的指针。 对于多维数组,这意味着您期望的多索引无法工作,因为该语言已经剥离了必要的大小和形状信息。
唯一的例外是参考参数不会以这种方式衰减。 但是,如果您依赖它,您(以及处理您的代码的任何其他人(将需要记住每次将多维数组传递给另一个函数时都使用该确切的引用参数。
在现代C++中,此问题通常使用std::array<>
修复,这是为此目的而设计的。 在您的情况下,这将非常冗长,所以我建议使用类型别名:
typedef std::array< std::array< std::array<SDL_Rect,
ANIMATION_FRAMES>, TOTAL_DIRECTIONS>, TOTAL_ACTIVITIES> SpriteClip;
std::vector<SpriteClip> gSpriteClips;
或者,你可以写一个简短的类:
class SpriteClip {
SDL_Rect m_data[TOTAL_ACTIVITIES][TOTAL_DIRECTIONS][ANIMATION_FRAMES];
public:
SDL_Rect& get(activity, direction, frame) {
return m_data[activity][direction][frame];
}
};
这样,您就可以轻松更改表示形式 - 例如,如果您决定希望不同的精灵具有不同数量的活动和帧。
- 编译包含指向模板函数的指针的初始值设定项列表时,gcc 出错,但 clang 不出错
- 当键是虚拟继承中涉及的基类指针时,对 std::unordered_map 项的访问崩溃
- 在C++中有多个指向单个对象的指针的正确方法是什么?
- 将指向多维数组向量中的单个项的指针传递给函数 c++
- 如何在单个链表中交换两个节点的位置,只修改指针
- 是否可以使用模板类的单个参数将类型和该类型的指针传递给 c++ 模板类?
- 如何使用 CMake 获得包含所有项目的 VS 解决方案和单个项目的解决方案
- 如何获取指向 qsort 第一个参数的向量中第一项的指针?
- 是否可以创建带有索引但没有指针的单个链表?
- 使用空大括号初始值设定项的重载分辨率:指针还是引用?
- 什么是 C# 中的双指针等效项
- 单个指针可以指向两个或多个变量吗?
- 指向单个项目或数组的指针
- 使用初始值设定项列表创建单个项向量
- 对象的"this"指针是否等于指向其(单个)基类的指针?
- 在C 中,将单个值写入一个非初始化的指针
- 如何为链表类实现单个项
- 使用“ static_cast”在空指针(单个或多个继承)上进行降低
- 什么是 NULL 的非指针等效项
- 指针——单个字符串与字符串数组