Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 树不维护递归上的迭代器成员_C++ - Fatal编程技术网

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