2011-09-13 10 views
0

私は以下のコードを持っています。ベクトルイテレータ

vector<IRD>* irds = myotherobj->getIRDs();//gets a pointer to the vector<IRD> 
for(vector<IRD>::iterator it = irds->begin(); it < irds->end(); it++) 
    { 
     IRD* ird = dynamic_cast<IRD*>(it); 
     ird->doSomething(); 
     //this works (*it).doSomething(); 

    } 

これは失敗するようです...私は、(* it)を使用せずにベクトルの各要素へのポインタを取得したいだけです。いたるところ。

  1. オブジェクトへのポインタを取得するにはどうすればよいですか?
  2. ベクトルポインタirdsを反復処理するとき、正確に何を繰り返すのですか?私が(* it)(。itSomething)、

答えて

5

と言うとき、それは各要素のコピーか、ベクトルの実際のオブジェクトで作業していますか?なぜポインタを取得しますか?誰もがイテレータ、ない<を比較する際に!=を使用して、言ったように、また

for(vector<IRD>::iterator it = irds->begin(); it != irds->end(); ++it) 
{ 
    it->doSomething(); 
} 

また
for(vector<IRD>::iterator it = irds->begin(); it != irds->end(); ++it) 
{ 
    IRD & ird = *it; 
    ird.doSomething(); 
} 

は、参照を使用してください。このケースでは動作しますが、別のコンテナを使用している場合は機能しなくなります(イテレータは下位のコンテナを抽象化するためのものです)。

+0

両方の質問にお答えいただき、ありがとうございました。 Cから来て...いつも参照型を忘れています...ある意味で抽象ポインタのようなものですか? – user623879

+0

@ user623879イテレータは、ポインタのように見えるように設計されています。実際、ポインタはイテレータの特別なケースとみなされます(実際には、生の配列のイテレータタイプです)。 –

0

&*itを実行すると、イテレータからポインタを取得できます。ベクトル内に格納されている実際のIRDオブジェクトへのポインタを取得します。ポインタを使ってオブジェクトを変更することができます。変更は "スティック"になります。これはベクトル内で持続します。

しかし、ベクトルには実際のオブジェクト(オブジェクトへのポインタではありません)が含まれているため、dynamic_castには何も表示されません。ポインタのタイプはIRD *で、IRDオブジェクトを指しています。

逆参照されたイテレータがコピー(またはより正確にはプロキシオブジェクト)を参照する可能性があるのは、ビットベクトルとして実装されるvector<bool>です。

2

ポインターのように、<ではなく、イテレーターを使用して末尾をテストする必要があります。<operator<vectorイテレータで動作しますが、コンテナを(listのようなものに)切り替えると、コードはコンパイルされなくなるので、一般的に!=を使用するとよいでしょう。

また、イテレータは、それが指す型ではありませんので、キャストしようとしないでください。イテレータでオーバーロードされたoperator->を使用できます。

vector<IRD>* irds = myotherobj->getIRDs();//gets a pointer to the vector<IRD> 
for(vector<IRD>::iterator it = irds->begin(); it != irds->end(); ++it) 
{ 
    it->dosomething(); 
} 
0

私は、ベクトルポインタIRDSを反復すると、私は正確に何を反復処理していますか?それぞれの要素のコピーであるか、私は(* it).doSomething()、

と言うとき、私はベクトル上の実際のオブジェクトで作業していますか?ベクトル全体を反復処理するときは、それのコピーではありません。

1

イテレータを参照して、基礎となるオブジェクトへの参照を取得します。

vector<IRD>* irds = myotherobj->getIRDs(); 
for(vector<IRD>::iterator it = irds->begin(); it != irds->end(); ++it) 
{ 
    IRD& ird = *it; 
    ird.doSomething(); 
    // alternatively, it->doSomething(); 
} 
0

通常のイディオムは、ポインタを取得するために&です。ダイナミックキャストはそれとは関係ありません。

1

実際に要素へのポインタが必要かどうか、イテレータを使用しようとしているだけで、イテレータを使用しないようにする場合は、最初に考慮してください。あなたがC++をコーディングするのではなく、C++でコーディングしようとしているようです。あなたが与えた例では、ポインタに変換してそのポインタで作業するのではなく、イテレータを直接使用するだけではないようです。 ird->doSomething()の代わりにit->doSomething()

後で作業をした後でそのポインタを保存する必要があると思っているのであれば、危険である可能性があります。ベクトルイテレータベクトルの要素へのポインタは無効にすることができます。つまり、もはやベクトルを指していないことを意味します。したがって、あなたはそれを解放した後に基本的にメモリを使用しようとします。イテレータを無効にできる一般的な例は、新しい要素を追加することです。私はイテレータを格納しようとしているという混乱に遭遇し、 "re_validate_iterator()"関数を書くことを含め、動作させるために多くの作業をしました。結局のところ、私のソリューションは非常に混乱していることが判明し、スケ​​ーラビリティに加えて、すべてのケースで動作しませんでした。

ベクトルの位置を保存しようとするのは、オフセットとして格納することです。要素内にあるベクトル内の位置を示す整数です。イテレータを使用する必要がある場合はmyvector.begin() + index、境界チェックを使用する要素自体への参照はmyvector.at (index)、境界チェックを必要としない場合はmyvector [index]のいずれかを使用してアクセスできます。

関連する問題