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 に答える