gpt4 book ai didi

c++ - 对象的变量在 vector 中重置(从 void* 转换)

转载 作者:太空狗 更新时间:2023-10-29 23:03:38 31 4
gpt4 key购买 nike

一些背景:

我正在制作的游戏中使用 Box2D。它有一种将“用户数据”存储到 Box2D 对象的方法。此“用户数据”采用 void*,因此可用于存储用户定义的数据。现在,当 Box2D 发生碰撞时,您可以使用此“用户数据”来识别发生碰撞的对象。然后您可以将数据转换为一个类,并访问该类的函数或变量(以及该类的特定实例,如果您已将“用户数据”设置为对该实例的引用)。我有两组“用户数据”,一组是对类实例的引用,另一组是对结构的引用,因此我可以检查对象的类型。

这适用于不在 vector 中的对象。我已经对此进行了测试,我可以访问类实例的函数和变量(并修改它们)而无需重置它们。 但是当我通过从 void* 强制转换访问我的 std::vector< Tile> 对象时,我修改的变量会立即重置。

相关代码:

我这样设置“用户数据”:

tile->SetUserData(static_cast<Entity*>(this));
ball->SetUserData(static_cast<Entity*>(this));

bUserData* bud = new bUserData;
bud->entityType = BALL;
ballFixture.userData = bud;

bUserData* bud = new bUserData;
bud->entityType = TILE;
tileFixture.userData = bud;

MyContactListener 类跟踪碰撞何时开始和结束,这也是从 void* 到 foo* 的转换发生的地方:

MyContactListener.cpp

std::vector<Tile> solidTiles;
Ball ball;

// Called when two objects begin to touch.
void MyContactListener::BeginContact(b2Contact* contact) {

// Cast from void* to a struct, from which I can check the object type.
bUserData* budA = (bUserData*)contact->GetFixtureA()->GetUserData();
bUserData* budB = (bUserData*)contact->GetFixtureB()->GetUserData();

// Cast from void* UserData to Entity* (super-class of all the entities).
Entity* entityA = (Entity*)contact->GetFixtureA()->GetBody()->GetUserData();
Entity* entityB = (Entity*)contact->GetFixtureB()->GetBody()->GetUserData();

if((budA->entityType == TILE && budB->entityType == BALL)) {
Tile* tile = (Tile*)entityA; // Tiles are in std::vector<Tile>
Ball* ball = (Ball*)entityB; // Only one ball instance exists

// Modifying a tile instance variable, gets reset to the original value immediately!
tile->flaggedToErase = true;
// This works fine!
ball->setColorToBlue = true;
}
}

问题:如何防止 vector 中的 tile 实例的变量被重置为原始值?

最佳答案

它应该是 TileTile* 的 vector 吗?我猜测,这个问题是由于使用存储对象拷贝的 vector<Tile> 而不是存储指向对象的指针的 vector<Tile*> 造成的。

比较这个:

std::vector< Tile > tiles;

Tile t;
t.foo = 123;
tiles.push_back( t ); // a copy of t is put into the vector

t.foo = 456; // changes t, but not the copy in the vector

Tile t2 = tiles[0]; // makes yet another copy (t2.foo == 123)

...用这个:

std::vector< Tile* > tiles;

Tile* t = new Tile;
t->foo = 123;
tiles.push_back( t ); // a pointer is put into the vector

t->foo = 456; // also changes in the vector because it's the same thing

Tile* t2 = tiles[0]; // still the same thing (t2->foo == 456)

如果你想要一个对象 vector (不是指针)并在 vector 中改变它们,你可以这样做:

std::vector< Tile > tiles;
Tile& t = tiles[0]; // note the ampersand, accesses by reference
t.foo = 456; // changes inside the vector

// I think you can also do this
tiles[0].foo = 456;

但是,要做到这一点,您需要有 vector 本身可用,并且您需要知道要更改的元素所在的位置。对于您的情况,您不知道元素在 vector 中的哪个位置,因此使用 vector<Tile*> 是最简单的解决方案。

关于c++ - 对象的变量在 vector 中重置(从 void* 转换),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24934602/

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