3

ベクトルを含むクラス(foo)があります。

次のように、ベクトル内の要素を反復処理しようとすると、次のようになります。

for(vector<random>::iterator it = foo.getVector().begin();
        it != foo.getVector().end(); ++it) {
  cout << (*it) << endl;

}

最初の要素は常に破損しており、ガベージデータを返します。

ただし、次のようなことを行う場合:

 vector<random> v = foo.getVector();
 for(vector<random>::iterator it = v.begin();
            it != v.end(); ++it) {
      cout << (*it) << endl;

 }

すべてが正常に機能しているようです。知らない「落とし穴」はありますか?

また、cout << foo.getVector()[0]<<endl;を実行してみました。ループの外側ですが、問題なく機能しているようです。

ありがとう。

編集:

これが私のヘッダーファイルです:

#ifndef HITS
#define HITS

#include <vector>
#include "wrappers.h"

class Hits {

    public:
        Hits();
        std::vector<word_idx_value> getVector() {return speech_hits;}
        const std::vector<word_idx_value> getVector() const {return speech_hits;}
        void add(const word_idx_value&);
        Hits &operator+=(const Hits&);
    private:
        std::vector<word_idx_value> speech_hits;
};

#endif
4

5 に答える 5

9
for(vector<random>::iterator it = foo.getVector().begin();

実行すると一時的なベクターが返され、その後に遭遇しfoo.getVector()た瞬間に破棄されます。したがって、ループ内でイテレーターは無効になります。;foo.getVector().begin();

の値を foo.getVector();ベクトル v ( v = foo.getVector();) に格納してからベクトル v を使用すると、正常に動作します。これは、ベクトル v がループ全体で有効であるためです。

于 2009-05-13T05:55:16.243 に答える
7

getVector() は、ベクトルを値で返します。getVector の 2 つの呼び出し (begin() と end()) は、ベクトルの異なるコピーを返すため、1 つのオブジェクトで begin() を呼び出し、別のオブジェクトで end() を呼び出します。得られるのは、2 つの異なるコンテナーへの 2 つのイテレーターです。これら 2 つの反復子を != で比較すると、未定義の値が返されます。

于 2009-05-13T05:55:00.690 に答える
2

getVector() はベクトルを値で返します。最初のケースでは、ループ内に入ると破棄される一時変数を取得します。2 番目のケースでは、ループ内でまだ生きているローカル変数に結果をコピーします。考えられる解決策は、const 参照によって vector を返すことです。

于 2009-05-13T05:56:17.880 に答える
1

エラーはgetVector()メソッドにあります。参照により返送してください。

class Hits
{
    public:
    std::vector<word_idx_value>&   getVector() {return speech_hits;}
    //                         ^
    //                      Add the & to return by reference.

    // You may also want a const version at some point.
    std::vector<word_idx_value> const&   getVector() const {return speech_hits;}

参照で戻らない場合は、一時的なコピーを作成しています。コピーは、使用後に破棄されます。この場合、begin()が実行された後、一時オブジェクトは破棄されるため、begin()によって返されるイテレータは無効です。

于 2009-05-13T14:14:35.680 に答える
0

getVector 関数を次のようにオブジェクト参照を返すように変更します: std::vector<word_idx_value>& getVector() {return speech_hits;}

于 2009-05-13T06:20:23.927 に答える