2

我正在为包含一组对象的数据库使用笨拙的 C 库接口。对象有一个类型,可以说 A 类型的对象包含一组 B 对象,依此类推。通过句柄访问对象,其定义如下:

typedef struct
{
    int handle;
} AHandleT; 


typedef struct
{
    int handle;
} BHandleT;

要遍历 A 对象的 B 子对象,使用以下函数:

ReturnT getB(AHandleT /*in*/, BHandleT* /*out*/)
ReturnT getBNext(BHandleT /*in*/, BHandleT* /*out*/)

同样对于迭代一组 B 对象:

ReturnT getC(BHandleT handle/*in*/, CHandleT* subHandle/*out*/)
ReturnT getCNext(CHandleT handle/*in*/, CHandleT* next/*out*/)

为了使用 C++ 中的这个接口,我制作了以下迭代器,我希望您能就其实现提出建议。另外,您认为这是一个好方法吗?请记住,我对 C++ 很陌生,我将使用 TDD 编写代码。

template<class HandleT>
class HandleIterator 
{
public:
    typedef ReturnT (*GetNext)(HandleT, HandleT*);

    HandleIterator(): m_isLast(true)
    {
    }

    template<class ParentHandleT>
    HandleIterator(const ParentHandleT parentHandle, ReturnT (*getFirstChild)(ParentHandleT, HandleT*), GetNext getNext): m_isLast(false), m_getNext(getNext)
    {
        ReturnT rc = getFirstChild(parentHandle, &m_currentHandle);
        if(rc == NotExisting)
        {
            m_isLast = true;
        }
    }

    void operator++()
    {
        ReturnT rc = m_getNext(m_currentHandle, &m_currentHandle);
        if(rc == NotExisting)
        {
            m_isLast = true;
        }
    }

    void operator++(int)
    {
        ++(*this);
    }

    const HandleT& operator*() const
    {
        return m_currentHandle;
    }

    const HandleT* operator->() const
    {
        return &m_currentHandle;
    }

    friend bool operator==(const HandleIterator& left, const HandleIterator& right)
    {
        return left.m_isLast == right.m_isLast;
    }

    friend bool operator!=(const HandleIterator& left, const HandleIterator& right)
    {
        return !(left == right);
    }

protected:
    HandleT m_currentHandle;
    bool m_isLast;
    GetNext m_getNext;
};

一旦有了句柄,我就可以使用以下形式的函数从 C 接口获取对象中包含的数据:

ReturnT getAName(AHandleT)
ReturnT getBName(BHandleT)
ReturnT getBOnlyProprty(BHandleT)

但这是下一个阶段。

等等

4

1 回答 1

1

您的实现非常好,尤其是对于初学者。

只是一些评论:

  • 在构造函数中,为什么getFirstChild直接传递而不是提供第一个孩子?
  • ++areT& operator++()和的规范签名T operator++(int)
  • ==应该比较超过m_isLast,否则会令人困惑。你也不能比较把手吗?

最后,在实现迭代器时,考虑继承自std::iterator. 它没有任何虚方法,但提供了typedef迭代器中通常期望的方法,并会提醒您需要选择一个类别:std::forward_iterator_tag很可能是这里。

于 2012-06-25T06:41:07.513 回答