【发布时间】:2025-12-29 22:05:16
【问题描述】:
我可以请求帮助以确认我的问题是否来自设计问题,或者是否有可能针对以下问题提供干净的解决方案:
实体.h
class CLEntity3D
{
public:
CLEntity3D();
virtual ~CLEntity3D();
virtual void update() = 0;
static std::vector<CLEntity3D*> vecEntity;
};
Entity.cpp
int CLEntity3D::nbrEntity = 0;
std::vector<CLEntity3D*> CLEntity3D::vecEntity;
CLEntity3D::CLEntity3D()
{
vecEntity.push_back(this);
}
CLEntity3D::~CLEntity3D()
{
vecEntity.erase((std::remove(vecEntity.begin(), vecEntity.end(), this)), vecEntity.end());
}
各种派生类正在通过程序创建/删除不同的实体对象,这一切都很好。
在一个场景类中,我有以下方法:
void CLScene::Update()
{
for (auto& iter : CLEntity3D::vecEntity) {
iter->update();
}
}
void CLScene::ClearScene()
{
for (auto& iter : CLEntity3D::vecEntity) {
delete(iter); iter = nullptr;
}
CLEntity3D::vecEntity.clear();
}
更新没问题,问题出在 ClearScene() 上。我得到一个“向量迭代器不兼容”的调试断言。
根据我的研究,常见问题似乎是因为迭代器来自不同的向量,我认为这不是问题所在。我认为问题在于调用 ClearScene() 时,每个 delete(iter) 通过 CLEntity3D 析构函数更改 vecEntity 的大小,因此使 ClearScene 循环中的迭代器无效。我说的对吗?
我的问题是: 有没有办法使用该设计从 CLScene 中删除所有 CLEntity3D 对象?
我想我可以让 CLScene 持有 vecEntity,这样可以消除问题,但这意味着 CLScene 必须管理所有实体的创建/删除,因此不能通用...
PS:我知道这个例子不是一个可以编译的例子,但是因为我的问题更多的是关于概念......请告知我是否应该提供其他方式。
【问题讨论】:
-
问题在于,在
CLEntity3D中,您将this添加到vecEntity向量中,但CLEntity3D实例可能是动态构造的,也可能不是动态构造的(例如CLEntity3D entity;vs.CLEntity3D *entity = new CLEntity3D();)。如果没有进行动态分配,则不能使用delete。 -
我猜你想写
*iter = nullptr;而不是iter = nullptr;如果你改变迭代器它应该怎么去下一个? -
@SHR 这是一个
for-range循环,iter变量实际上是指针本身,而不是迭代器。 -
@SHR 那里不是迭代器,他使用的是基于范围的 for 循环。
-
有充分的理由让每个
CLScene管理它自己的私有实体列表,而不是作为CLEntity3D的静态成员并由CLEntity3D管理。一方面,它将代码打开到多个场景的可能性。对于另一个vecEntity是公开的。任何人都可以随时删除任何实体,让CLScene处于非常危险的境地。