c++ - 为写入指针 API 创建行为良好的迭代器

标签 c++ pointers stl iterator ogr

我必须为仅具有旧式“写出指针”访问器的 API 创建迭代器。有问题的 API 是 OGR 的;有问题的类之一是 OGRLineString(供引用:Link)。这个类存储了一些点,可以使用下面的 getter 方法访问它们:

 void OGRLineString::getPoint(int pos, OGRPoint *out)

为了使用访问器,创建一个新的 OGRPoint 对象并将指向它的指针传递给方法,该方法将数据写入分配的对象。例如:

OGRPoint *p = new OGRPoint();
lineString->getPoint(0, p);

现在,我想实现一个(类似 STL 的)迭代器。即使我在各处都放置了很大的警告标志,说明所提供的 OGRPoint 是不可修改的(即 const),并且如果另一段代码修改了OGRLineString 正在迭代,我遇到了 OGRPoint const &operator*() const 的内存泄漏问题,因为 API 要求我传递自定义分配的 OGRPoint 实例,但迭代器必须分配一个。另外,当迭代器本身被删除时,迭代器返回的 OGRPoint 不应该被删除。此外,OGRLineString 不存储为 getPoint 复制的 OGRPoint 的实际实例,而是存储 x/y/z 坐标的简单结构;所有必需的附加信息(例如,空间引用)都复制到访问器中。因此,一个简单的#define private public hack 将无济于事。

有没有任何明智/干净的方法来添加迭代器而不修改OGRLineString 的原始源代码?例如,有没有办法向原始类添加功能或修改它,就像 Ruby 的“猴子修补”功能一样?或者观察容器的生命周期以清理迭代器返回的 OGRPoint 实例?

最佳答案

这假设 OGRPoint 是可复制构造的。如果没有,请使用智能指针。

#include <iterator>

#include <ogr_geometry.h>

struct OGR_SimpleCurve_Points_Iterator : std::iterator< std::random_access_iterator_tag, const OGRPoint >
{
    OGR_SimpleCurve_Points_Iterator( OGRSimpleCurve* curve=nullptr, int index=0 )
        : curve(curve), index(index) {}

    OGR_SimpleCurve_Points_Iterator& operator++() { ++index; return *this; }
    OGR_SimpleCurve_Points_Iterator operator++(int) { OGR_SimpleCurve_Points_Iterator ret(*this); ++index; return ret; }
    OGR_SimpleCurve_Points_Iterator& operator--() { --index; return *this; }
    OGR_SimpleCurve_Points_Iterator operator--(int) { OGR_SimpleCurve_Points_Iterator ret(*this); --index; return ret; }

    OGR_SimpleCurve_Points_Iterator& operator+=(int n) { index+=n; return *this; }
    OGR_SimpleCurve_Points_Iterator& operator-=(int n) { index-=n; return *this; }

    OGR_SimpleCurve_Points_Iterator operator+(int n) { return OGR_SimpleCurve_Points_Iterator{curve,index+n}; }
    OGR_SimpleCurve_Points_Iterator operator-(int n) { return OGR_SimpleCurve_Points_Iterator{curve,index-n}; }

    int operator-(const OGR_SimpleCurve_Points_Iterator& other) { return index-other.index; }

    OGRPoint operator*() { OGRPoint p; curve->getPoint(index,&p); return p; }

    OGRPoint operator[](int ofs) { OGRPoint p; curve->getPoint(index+ofs,&p); return p; }

    bool operator == ( const OGR_SimpleCurve_Points_Iterator& other ) { return index==other.index; }
    bool operator != ( const OGR_SimpleCurve_Points_Iterator& other ) { return index!=other.index; }
    bool operator  > ( const OGR_SimpleCurve_Points_Iterator& other ) { return index >other.index; }
    bool operator >= ( const OGR_SimpleCurve_Points_Iterator& other ) { return index>=other.index; }
    bool operator  < ( const OGR_SimpleCurve_Points_Iterator& other ) { return index <other.index; }
    bool operator <= ( const OGR_SimpleCurve_Points_Iterator& other ) { return index<=other.index; }

private:
    OGRSimpleCurve* curve;
    int index;
};

OGR_SimpleCurve_Points_Iterator begin( OGRSimpleCurve* curve )
{
    return OGR_SimpleCurve_Points_Iterator{curve};
}

OGR_SimpleCurve_Points_Iterator end( OGRSimpleCurve* curve )
{
    return OGR_SimpleCurve_Points_Iterator{curve,curve->getNumPoints()};
}

关于c++ - 为写入指针 API 创建行为良好的迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27969824/

相关文章:

c++ - 转换运算符转换为仅模板参数不同的类?

c - 如何修复将指针强制转换为整数?

python - 如果我要使用一个变量,我必须总是在我的函数中将它引用为全局变量吗?

c - 返回指向静态定义的结构数组的指针

c++ - 如何避免第三方库(无源代码)从物理内存分配内存?

c++ - 写入二进制文件?

c++ - 从队列中显示二维数组后程序崩溃

c++ - 如何在 C++ 中打乱指针列表?

c++ - 作为结构内部字段的映射的初始化值?

c++ - 无论如何,模板不是用作参数,而是用作全局类型吗?