はいそれではコンテナ用イテレータの種類について書いていきます。
前回、前々回の記事でQVector,QLindedlist,QListについて書きましたが、そのサンプル内でイテレータを使ったものがあったかと思います。Qtでは
①Javaスタイルイテレータ
②STLスタイルイテレータ
の2種類が用意されています。今回はSTLスタイルイテレータについて書いていきます。(イテレータについてはWikiでも見てください。)②STLスタイルイテレータ
C<T>::iteratorとC<T>::const_iteratorの2種類がこれに当たります。constなしが読み書きOK、const...のほうが読み込みのみという違いです。このSTLイテレータが指す要素はJavaスタイルイテレータとは違い、要素そのものを指します。以下のような感じです。
STLイテレータはC++のポインタのように使用できます。よってかなり使い易いです。
それではサンプルを書いていきます。(C++ GUI Programming with Qt4 256ページを参考)
いつものようにQtCreaterの使用を前提とします。(QtCreaterなどの使い方は ”Qtをはじめよう" を見てください。)
ではコードを
(C<T>::const_iteratorのサンプル ※読み込みのみ)
QList<QString> list;
list << "One!" << "Two!" << "T";
QList<QString>::const_iterator i = list.begin();
bool T_exist = false;//"T"が含まれているかどうかのフラグ
while(i != list.end())//iが最後のうしろ以外ならループ
{
    if(*i == "T")
    {
        T_exist = true;
        break;
    }
    i++;//次の要素へ
}
//最終的にT_existにはtrueが入ります。
はい簡単ですね。流れはlistのSTLのconstイテレータを取り出し、"T"が含まれているか走査しているだけです。
begin()やend()はSTLスタイルイテレータを返します。(リファレンス)
beginは最初の要素、endは最後の後ろの要素を指します。
(C<T>::iteratorサンプル ※読み書きOK)
QList<QString> list;
list << "One!" << "Two!" << "T";
QList<QString>::iterator i = list.begin();
while(i != list.end())
{
    if(*i == "T")//"T"の値ならば↓
    {
        *i = "Three!";//"Three!"に書き換え
        break;
    }
    i++;
}
//最終的にlistは[ "One!", "Two!", "Three!" ]となる
これも簡単ですね。実際はこちらのほうをよく使うと思います。流れはlistのSTLイテレータを取り出し、"T"が含まれているか走査して、あればその指し示す要素を"Three!"に書き換えているだけです。
(その他の詳細についてはリファレンスを参照してみてください。)
なお、Qtでコンテナクラスを返す関数がありますが、以下のように
//このコードは危険
QList<int>::const_iterator i = splitter->sizes().begin();
while (i != splitter->sizes().end()) {
//...
++i;
}
//このコードは危険
のようアクセスするのはマズイようです。どうもループの先頭でsize()を呼んだ際にリストが自動で消去されイテレータの宙ぶらりんの参照先が残ってしまうからだそうです。しかも悪いことにループを実行するたびsplitter->sizes().end()を呼び出すので、そのループのたびにリストの新しいコピーを生成してしまうことになるそうです。なんだか要素が多いときを考えるとゾッとしますね。
これを避けるには以下のように
QList<int> list = splitter->sizes();//listにコピー
QList<int>::const_iterator i = list.begin();
while (i != list.end()) {
//...
++i;
}
//これは安全
必ず返されたコンテナクラスをコピーしてから反復処理を開始すれば安全だそうです。(C++ GUI Programming with Qt4 257ページに詳細が書かれています。)
以上です。
 


