离开成功使用 std::erase 的方法后删除了错误的元素
Wrong element is removed after leaving method which used std::erase succesfully
我正在研究图形引擎。引擎有 std::vector
个可绘制对象。 Drawable 是一个包含 Model 和 DrawableObject 的对象,DrawableObject 又包含着色器程序和来自 2D 或 3D 模型的一堆顶点。添加新的 Drawable 很顺利,当我尝试删除 Drawable 时出现问题。最后一个 Drawable 将始终被删除,倒数第二个将更改其值。
代码
Drawable.h
class Drawable
{
public:
Drawable& operator=(const Drawable& other)
{
Drawable tmp(other);
std::swap(model, other.model);
std::swap(drawableObject, other.drawableObject);
return *this;
}
Drawable(domain::Model& model, DrawableObject& drawableObject) :
model(model),
drawableObject(drawableObject)
{}
domain::Model& model;
DrawableObject& drawableObject;
};
game.cpp
void Game::init_game()
{
human = domain::Model(glm::vec3(0, 0, -3));
moveables.push_back(&human);
room = domain::Model(glm::vec3(0, 0, -10));
props.push_back(&room);
cube = domain::Model(glm::vec3(0, 0, 0));
props.push_back(&cube);
}
void Game::init_graphics_engine()
{
// ... load graphics models
// add drawables
graphicsEngine->add(cube, Drawable::CUBE);
graphicsEngine->add(human, Drawable::HUMAN);
graphicsEngine->add(room, Drawable::ROOM);
graphicsEngine->add(topDownScene->cursor, Drawable::MARKER);
}
graphics_engine/engine.cpp
void Engine::add(domain::Model& model, unsigned int object)
{
auto drawableObject = drawableObjects[object];
// make sure not to add a model that already is represented
auto it = std::find_if(drawables.begin(), drawables.end(), [&model](Drawable& drawable) {return &drawable.model == &model;});
if(drawableObject && it == drawables.end())
drawables.push_back(Drawable(model, *drawableObject));
}
void Engine::remove(domain::Model& model)
{
auto predicate = [&model](Drawable& drawable)
{
return &drawable.model == &model;
};
drawables.erase(std::remove_if(drawables.begin(), drawables.end(), predicate), drawables.end());
}
场景
这是我启动应用程序时的场景:
这是尝试擦除中间的小 'human' 立方体后的场景:
代码删除了最后一个 Drawable,即白色标记,而不是 'human' 立方体,并更改了房间的 z 位置。这几乎总是发生,它删除了最后一个元素并将第二个元素的 z 更改为倒数第二个。仅当我在 init 方法中最后添加 'human' 多维数据集时才有效。
断点
删除对象之前:
删除对象后:
这是正确的。
离开移除方法并查看渲染循环:
不知何故改变了。
我将 class 成员更改为指针。现在可以了。评论是对的,我没有对tmp
变量做任何事情。
class Drawable
{
public:
Drawable& operator=(const Drawable& other)
{
this->model = other.model;
this->drawableObject = other.drawableObject;
return *this;
}
Drawable(domain::Model* model, std::shared_ptr<DrawableObject> drawableObject) :
model(model),
drawableObject(drawableObject)
{}
domain::Model* model;
std::shared_ptr<DrawableObject> drawableObject;
};
我正在研究图形引擎。引擎有 std::vector
个可绘制对象。 Drawable 是一个包含 Model 和 DrawableObject 的对象,DrawableObject 又包含着色器程序和来自 2D 或 3D 模型的一堆顶点。添加新的 Drawable 很顺利,当我尝试删除 Drawable 时出现问题。最后一个 Drawable 将始终被删除,倒数第二个将更改其值。
代码
Drawable.h
class Drawable
{
public:
Drawable& operator=(const Drawable& other)
{
Drawable tmp(other);
std::swap(model, other.model);
std::swap(drawableObject, other.drawableObject);
return *this;
}
Drawable(domain::Model& model, DrawableObject& drawableObject) :
model(model),
drawableObject(drawableObject)
{}
domain::Model& model;
DrawableObject& drawableObject;
};
game.cpp
void Game::init_game()
{
human = domain::Model(glm::vec3(0, 0, -3));
moveables.push_back(&human);
room = domain::Model(glm::vec3(0, 0, -10));
props.push_back(&room);
cube = domain::Model(glm::vec3(0, 0, 0));
props.push_back(&cube);
}
void Game::init_graphics_engine()
{
// ... load graphics models
// add drawables
graphicsEngine->add(cube, Drawable::CUBE);
graphicsEngine->add(human, Drawable::HUMAN);
graphicsEngine->add(room, Drawable::ROOM);
graphicsEngine->add(topDownScene->cursor, Drawable::MARKER);
}
graphics_engine/engine.cpp
void Engine::add(domain::Model& model, unsigned int object)
{
auto drawableObject = drawableObjects[object];
// make sure not to add a model that already is represented
auto it = std::find_if(drawables.begin(), drawables.end(), [&model](Drawable& drawable) {return &drawable.model == &model;});
if(drawableObject && it == drawables.end())
drawables.push_back(Drawable(model, *drawableObject));
}
void Engine::remove(domain::Model& model)
{
auto predicate = [&model](Drawable& drawable)
{
return &drawable.model == &model;
};
drawables.erase(std::remove_if(drawables.begin(), drawables.end(), predicate), drawables.end());
}
场景
这是我启动应用程序时的场景:
这是尝试擦除中间的小 'human' 立方体后的场景:
代码删除了最后一个 Drawable,即白色标记,而不是 'human' 立方体,并更改了房间的 z 位置。这几乎总是发生,它删除了最后一个元素并将第二个元素的 z 更改为倒数第二个。仅当我在 init 方法中最后添加 'human' 多维数据集时才有效。
断点
删除对象之前:
删除对象后:
这是正确的。
离开移除方法并查看渲染循环:
不知何故改变了。
我将 class 成员更改为指针。现在可以了。评论是对的,我没有对tmp
变量做任何事情。
class Drawable
{
public:
Drawable& operator=(const Drawable& other)
{
this->model = other.model;
this->drawableObject = other.drawableObject;
return *this;
}
Drawable(domain::Model* model, std::shared_ptr<DrawableObject> drawableObject) :
model(model),
drawableObject(drawableObject)
{}
domain::Model* model;
std::shared_ptr<DrawableObject> drawableObject;
};