C++ 树不维护递归上的迭代器成员
我正在构建一个简单的边界卷层次结构,在二叉搜索树结构中实现。有时,一个树节点最终会附着多个对象(例如,如果它们的质心位于同一位置)。因此,我必须让每个节点维护一个对象集合,而不是一个指针 我试图通过迭代器让每个树节点包含对象集合的特定片段来实现这一点。在生成树时分发它们似乎工作正常,但在检索叶时迭代器不知何故会损坏 代码的简化版本:C++ 树不维护递归上的迭代器成员,c++,C++,我正在构建一个简单的边界卷层次结构,在二叉搜索树结构中实现。有时,一个树节点最终会附着多个对象(例如,如果它们的质心位于同一位置)。因此,我必须让每个节点维护一个对象集合,而不是一个指针 我试图通过迭代器让每个树节点包含对象集合的特定片段来实现这一点。在生成树时分发它们似乎工作正常,但在检索叶时迭代器不知何故会损坏 代码的简化版本: #include <iostream> #include <cstdlib> #include "util.h" #include <
#include <iostream>
#include <cstdlib>
#include "util.h"
#include <vector>
#include <algorithm>
using namespace std;
class Point {
public:
Point() : x(0), y(0) {}
Point(double x, double y) : x(x), y(y) {}
double x;
double y;
};
Point elementWiseMin(Point a, Point b) {
return Point(min(a.x, b.x), min(a.y, b.y));
}
Point elementWiseMax(Point a, Point b) {
return Point(max(a.x, b.x), max(a.y, b.y));
}
class BoundingBox {
public:
BoundingBox(Point minCorner, Point maxCorner) : minCorner(minCorner), maxCorner(maxCorner) {}
Point minCorner;
Point maxCorner;
};
class Shape {
public:
Shape(BoundingBox* obj, Point x) : boundingBox(obj), centroid(x) {}
BoundingBox* boundingBox;
Point centroid;
};
typedef vector<Shape*> ShapeContainer;
class Tree {
public:
Tree(ShapeContainer::iterator begin, ShapeContainer::iterator end) :
begin(begin), end(end), hasNodes(true) {
cout << end - begin << "\n";
if (end - begin < 1) hasNodes = false;
else {
minCorner = (*begin)->boundingBox->minCorner;
maxCorner = (*begin)->boundingBox->maxCorner;
for (ShapeContainer::iterator i = begin + 1; i < end; i++) {
minCorner = elementWiseMin(minCorner, (*i)->boundingBox->minCorner);
maxCorner = elementWiseMax(maxCorner, (*i)->boundingBox->maxCorner);
}
double split = minCorner.x + ((maxCorner.x - minCorner.x) / 2);
splitAt = split;
ShapeContainer::iterator middle = partition(begin, end,
[split](Shape* n) {
return n->centroid.x < split;
});
if (middle - begin > 0 && end - middle > 0) {
Tree c1 = Tree(begin, middle);
child1 = &c1;
Tree c2 = Tree(middle, end);
child2 = &c2;
}
}
}
ShapeContainer::iterator begin;
ShapeContainer::iterator end;
Point minCorner;
Point maxCorner;
Tree* child1 = nullptr;
Tree* child2 = nullptr;
bool hasNodes;
double splitAt;
//get the node at x
Tree* getNode(int x) {
cout << end - begin << "\n";
if (x < splitAt) {
if (child1 == nullptr) return this;
else return child1->getNode(x);
}
else {
if (child2 == nullptr) return this;
else return child2->getNode(x);
}
}
};
int main() {
ShapeContainer container;
Shape shape1 = Shape(new BoundingBox(Point(0, 0), Point(1, 1)), Point(0.5, 0.5));
container.push_back(&shape1);
Shape shape2 = Shape(new BoundingBox(Point(-2, 0), Point(-1, 1)), Point(-1.5, 0.5));
container.push_back(&shape2);
Shape shape3 = Shape(new BoundingBox(Point(2, 0), Point(3, 1)), Point(2.5, 0.5));
container.push_back(&shape3);
Shape shape4 = Shape(new BoundingBox(Point(4, 0), Point(5, 1)), Point(4.5, 0.5));
container.push_back(&shape4);
cout << "Generate tree\n";
Tree t = Tree(container.begin(), container.end());
cout << "Traverse tree\n";
Tree* node = t.getNode(-1);
return 0;
}
生成时的输出正是我所期望的,但迭代器似乎没有正确地保存到子级。在
树
构造函数的末尾,您将局部变量的地址分配给树
类(child1=&c1
)的一个成员。这是不好的,因为几行之后,c1
对象超出范围,将被销毁。这使得child1
(和child2
)成为悬空指针,因为它们指向的对象不再有效
您可能希望使用动态内存分配(使用
unique\u ptr
或shared\u ptr
)来正确构造树。在树的构造函数末尾,您将局部变量的地址分配给树类(child1=&c1
)的一个成员。这是不好的,因为几行之后,c1
对象超出范围,将被销毁。这使得child1
(和child2
)成为悬空指针,因为它们指向的对象不再有效
您可能希望使用动态内存分配(使用unique\u ptr
或shared\u ptr
)来正确构建树。有没有快速方法将“return this”更改为this的unique\u ptr,或者我必须修改它以返回它的子项吗?将child1
和child2
更改为std::unique\u ptr
(而不是Tree*
),并为它们分配类似child1=std::make\u unique(开始,中间)
代替您当前为每个子项设置的两行。是否有快速方法将“return this”(返回此项)更改为唯一的子项,或者我是否需要重新编写此项以返回其子项?将child1
和child2
更改为std::unique_ptr
(而不是Tree*
),并为它们分配类似于child1=std::make_unique(begin,middle)的内容代码>取代当前为每个子项提供的两行。除了给出的答案外,您的代码还存在许多内存泄漏,并试图复制不可安全复制的形状
对象。您打算如何释放分配给new
的所有内存?除了给出的答案外,您的代码还存在许多内存泄漏,并试图复制形状
无法安全复制的对象。您打算如何释放分配给new
的所有内存?
Generate tree
4
2
1
1
2
1
1
Traverse tree
4
-47673