2003年4月28日月曜日

最近、C++ の変な使い方を覚えた

C++ のコレクション・クラスを作っています。設計は STL よりも Java のコレクションに近いもので、 template を使わずに void* でデータを保持するようになっています。
大体の部分はオーソドックスな作りなんですが、イテレータ周りは、 List クラスから イテレータを作る時にポインタで返すのが嫌だった
開放しわすれが多くなりそうだし、イテレータのデリファレンスが p->Get() もしくは *(*p) と不格好になる..
ので、試行錯誤していたら結構トリッキーな物ができてしまいました。
日記に長々と書くのはあれですが、骨子だけ書くと、

class IteratorRaw {
virtual void*& Get() const = 0;
virtual void* Inc() const = 0;
};
class Iterator {
IteratorRaw *_body;
public:
Iterator(IteratorRaw* body) : _body(body) {}
void*& operator*() { return _body->Get(); }
Iterator& operator++() { _body->Inc(); return *this; }
};

見たいな感じで、ユーザーは Iterator を使い、 List クラス等で Iterator を作る時は、 List クラス内部に IteratorRaw を継承したクラスを作って、 Iterator 作成時にそれを new して Iterator のコンストラクタに渡すようになっています。
効率は、イテレータを使う時ならば、(template を使わずに)普通に継承をして、ポインタを経由で使うものと変わらないはずです。イテレータを作る時は... どうなんだろ。 Iterator を作る時にクラスの new/delete がいくつか発生するけど、書き方を工夫、もしくはコンパイラが頑張れば delete は無くせる気がするんだけど。

0 件のコメント:

コメントを投稿