复合数据结构和摆弄指针

Compound data structure and fiddling with pointers

本文关键字:指针 摆弄 数据结构 复合      更新时间:2023-10-16

我正在尝试创建一个由四叉树和简单 STL 向量组成的复合数据结构类,因为我希望能够跨时间范围访问数据(即保持插入对象的顺序)。我最初的实现是维护一个 MyObject 的 STL 向量和一个const MyObject * const的四叉树。

不用说,在那之后的一段时间里,我才意识到在删除这个复合数据结构的那一刻,无法保证首先删除四叉树和 STL 向量(保存底层数据),因此可能会出现内存问题。

我正在考虑在插入新对象时在堆上创建一个MyObject实例,并且四叉树和 STL 向量基本上都保存了指向该对象的指针(使用 shared_ptr 或其他东西?

有什么更好的建议吗?

编辑:这是我到目前为止的实现。我认为只有insertretrieve...函数可能感兴趣

头文件:

#include "MapQuadTree.hpp"
typedef cv::Point2d Coordinate_t;
class PointsData
{
private:
    const unsigned int mMaxLevels = 10;
    const unsigned int mMaxPerLevel;
    unsigned int mMaxDataSize;
    unsigned int mCurrentIndex;
    std::vector<Coordinate_t> mPointsVector;
    MapQuadTree mPointsQuadtree;
public:
    PointsData(const unsigned int maxDataSize, double mapWidth, double mapHeight);
    ~PointsData();
    Coordinate_t operator[](int index);
    Coordinate_t last();
    Coordinate_t first();
    bool insert(const Coordinate_t& point);
    void retrieveNeighboringPoints(const Coordinate_t& point, std::vector<Coordinate_t>& neighbors);
};

源文件:

#include "PointsData.hpp"

PointsData::PointsData(const unsigned int maxDataSize, double mapWidth, double mapHeight)
: mMaxPerLevel(maxDataSize / mMaxLevels), mMaxDataSize(maxDataSize), mPointsVector(maxDataSize), mCurrentIndex(0),
mPointsQuadtree(0, maxDataSize / mMaxLevels, mMaxLevels, Coordinate_t(-1.0*mapWidth/2, -1.0*mapHeight/2), mapWidth, mapHeight)
{
}

PointsData::~PointsData()
{
}

Coordinate_t PointsData::operator[](int index)
{
    return mPointsVector[index];
}
Coordinate_t PointsData::last()
{
    return mPointsVector.back();
}
Coordinate_t PointsData::first()
{
    return mPointsVector.front();
}
bool PointsData::insert(const Coordinate_t& point)
{
    if (mCurrentIndex >= mMaxDataSize)
        return false;
    mPointsVector[mCurrentIndex] = point;
    mPointsQuadtree.insert(&mPointsVector[mCurrentIndex]);
    mCurrentIndex++;
    return true;
}
void PointsData::retrieveNeighboringPoints(const Coordinate_t& point, std::vector<Coordinate_t>& neighbors)
{
    std::vector<const Coordinate_t * const> results;
    mPointsQuadtree.retrieve(point, results);
    neighbors.clear();
    for (const Coordinate_t * const elemPtr : results) {
        neighbors.push_back(*elemPtr);
    }
}
内存

管理应委托给容器。一个可能的建议应该是在向量中使用智能指针,如下所示: std::vector<std::shared_ptr<MyObject>>是否共享保存对象的内存,或者std::vector<std::unique_ptr<MyObject>>该内存是否不共享。

我认为您的原始设计没有特别的问题。

只有在销毁向量后尝试取消引用四叉树中的指针时,才会遇到内存问题。实际的销毁顺序并不那么重要。

如果四叉树和向量都由同一个对象管理,它们将被管理对象的析构函数大约同时销毁,一切都会好起来的。