我遇到了std::vector
被清除的问题,但我无法弄清楚在哪里。我花了很多时间来调试这个问题,并且不能在我的生活中找到它被清除的地方。
代码:
class ENGINE_API QuadTree {
private:
typedef std::unordered_set<QuadTreeObject*> EntityContainer;
typedef std::vector<QuadTree> ChildContainer;
const static int MAX_OBJECTS = 5;
AABB bounds;
ChildContainer children;
EntityContainer entities;
EntityContainer allEntities;
// Internal methods
void split();
int getIndex(const AABB&)const;
template <class T>
void merge(T& one, const T& two) {
one.insert(two.begin(), two.end());
}
// End Internal methods
public:
QuadTree(AABB bounds) : bounds(bounds), children(), entities(), allEntities() {
children.reserve(4);
}
// Base
void clear() {
entities.clear();
allEntities.clear();
children.clear();
}
void insert(QuadTreeObject*);
void remove(QuadTreeObject*, const AABB&);
// Not the source, I've removed this and it still works fine (Nothing uses this method)
ChildContainer& getChildren() {
return children;
}
AABB& getBounds() {
return bounds;
}
QuadTree getLowestRoot(const AABB& aabb)const {
int index = getIndex(aabb);
if (index == -1 || children.empty()) {
return *this;
}
return children.at(index).getLowestRoot(aabb);
}
const EntityContainer& getAll()const {
return allEntities;
}
// End Base
};
void QuadTree::split() {
children.clear(); // supposed to be there
double width = (bounds.getWidth() / 2);
double height = (bounds.getHeight() / 2);
children.push_back(QuadTree(AABB(bounds.min.x + width, bounds.min.y, width, height)));
children.push_back(QuadTree(AABB(bounds.min.x, bounds.min.y, width, height)));
children.push_back(QuadTree(AABB(bounds.min.x, bounds.min.y + height, width, height)));
children.push_back(QuadTree(AABB(bounds.min.x + width, bounds.min.y + height, width, height)));
auto it = entities.begin();
while (it != entities.end()) {
int index = getIndex((*it)->getAABB());
if (index != -1) {
children.at(index).insert(*it);
it = entities.erase(it);
}
else {
it++;
}
}
}
int QuadTree::getIndex(const AABB& aabb)const {
// Fits in top
bool topQuadrant = aabb.max.y < aabb.horzMid;
// Fits in botom
bool bottomQuadrant = aabb.min.y > aabb.horzMid;
// Fits in left
if (aabb.max.x < aabb.vertMid) {
if (topQuadrant) {
return 1;
}
else if (bottomQuadrant) {
return 2;
}
}
// Fits in right
else if (aabb.min.x > aabb.vertMid) {
if (topQuadrant) {
return 0;
}
else if (bottomQuadrant) {
return 3;
}
}
return -1;
}
void QuadTree::insert(QuadTreeObject* object) {
AABB aabb = object->getAABB();
allEntities.insert(object);
if (children.empty()) {
if (entities.size() <= MAX_OBJECTS) {
entities.insert(object);
return;
}
split();
}
int index = getIndex(aabb);
if (index != -1) {
children.at(index).insert(object);
}
else {
entities.insert(object);
}
}
void QuadTree::remove(QuadTreeObject* object, const AABB& aabb) {
if (!allEntities.erase(object)) {
return;
}
if (!entities.erase(object)) {
if (!children.empty()) {
int index = getIndex(aabb);
if (index != -1) {
children.at(index).remove(object, aabb);
}
else {
throw std::logic_error("Can't be in allEntities but not entities!");
}
}
else {
throw std::logic_error("Can't be in allEntities but not entities!");
}
}
}
调用split
方法时,children.size()
返回4,但到达insert
时,它再次为0。这怎么可能?
答案 0 :(得分:2)
这是一个问题:
class ENGINE_API QuadTree {
typedef std::vector<QuadTree> ChildContainer;
ChildContainer children;
在完成类定义之前, QuadTree
是一个不完整的类型。如果您使用std::vector
类型不完整,则行为未定义。
换句话说,一个类不能包含它自己的向量。你将不得不重新设计你的课程,例如: