2012-01-05 8 views
0

私は、ある関数に値渡しするポインタのベクトルを消去しようとしています。値を渡す理由は、関数への多数の呼び出しでこれらの値を消去することを計画しているからです。だから私がポインタ/参照を渡す場合、私はこれを達成できませんでした。ポインタのベクトルを渡して重複を削除する

まずは上記の文は正しいですか?ここで

は、いくつかのサンプルコードです:

vector<Boson*>* BosonMaker::remove_duplicates(vector<Boson*>* boson_candidates, vector<Particle*> child_candidates){ 
    vector<Particle*> used_leptons.clear(); 

    // This needs deleting at some point 
    m_unduplicated_bosons = new vector<Boson*>(); 

    for(int i_b = 0; boson_candidates->size(); i_b++){ 

    vector<Particle*>::iterator child1_finder = find(used_leptons.begin(), used_leptons.end(), boson_candidates->at(i_b)->Child1()); 

    //Search pointer will reach end of collection if child isn't in the used_leptons vector 
    if (child1_finder == used_leptons.end()) { 
     vector<Particle*>::iterator child2_finder = find(used_leptons.begin(), used_leptons.end(), boson_candidates->at(i_b)->Child2()); 

     if (child2_finder == used_leptons.end()) { 
     used_leptons.push_back(boson_candidates->at(i_b)->Child1()); 
     used_leptons.push_back(boson_candidates->at(i_b)->Child2()); 
     // And add the boson to the vector of final bosons 
     unduplicated_bosons->push_back(boson_candidates->at(i_b)); 
     } 
    } 

    } 
    // Now make a vector of unused leptons 
    for (int i_l = 0; i_l < used_leptons.size(); i_l++) { 
     vector<Particle*>::iterator lepton_finder = find(child_candidates.begin(), child_candidates.end(), used_leptons.at(i_l)); 
     child_candidates.erase(lepton_finder); 
    } 

    return unduplicated_bosons; 
} 

私はその後、私の質問があるので、

vector<Boson*> *m_boson_finals_elpair = remove_duplicates(&m_boson_electronPair_candidates, m_all_particle_candidates); 
vector<Boson*> *m_boson_finals_mupair = remove_duplicates(&m_boson_muonPair_candidates, m_all_particle_candidates); 

vector<Boson*> *m_boson_finals_elneutrino = remove_duplicates(&m_boson_electronNeutrino_candidates, m_all_particle_candidates); 
vector<Boson*> *m_boson_finals_muneutrino = remove_duplicates(&m_boson_muonNeutrino_candidates, m_all_particle_candidates); 

のようにクラス内でこのメンバ関数を使用します。

ある

うとm_all_particle_candidates

vector<Particle*> m_all_particle_candidates; 

はremove_duplicatesの呼び出しごとに異なっていますか?

私は値渡しのため、実際のオブジェクトではなくベクトルから消去されたイテレータlepton_finderを質問しようとしていますか?

注:remove_duplicate関数にタイプミスがありました。私はポインタではなく値を渡した。それは値でなければなりません

+0

私はここであなたの質問に答えました:http://stackoverflow.com/questions/1041620/most-efficient-way-to-erase-duplicates-and-sort-ac-vector/14844222#14844222 ptgi: :メモリリークを避けるためのstd :: unique()の置き換え、重複した削除、および分割の失敗を記述するunique()記事。 -dbednar ahd 310 – joe

答えて

0

あなたは価値によってベクトルを渡していません。

vector<Boson*>* BosonMaker::remove_duplicates(vector<Boson*>* boson_candidates, vector<Particle*> *child_candidates); 

によってvectorへのポインタを通過します。しかし、元のもののコピーであるポインタは、オリジナルと同じvectorを指します。

基本的には、通話外の同じベクトルを変更しています。値渡しするには

、次のものが必要です。

vector<Boson*>* BosonMaker::remove_duplicates(vector<Boson*> boson_candidates, vector<Particle*> child_candidates); 

しかし、そうする際に注意してください。コピーが発生するので、BosonParticleの仮想デストラクタ、コピーコンストラクタ、代入演算子をオーバーライドする必要があります(PODタイプでない場合はおそらく)。

+0

申し訳ありませんremove_dupilicatesコード – MWright

+0

@MWrightの場合は、新しいプロトタイプで質問を編集してください。その場合、私があなたが言っていたものを上書きするようにしてください。 –

1

は、私はあなたが値渡しと参照渡しについて言っているかについて少し困惑しているので、私はその最初に簡単な説明を与えるつもりだ:

  • 値渡し、メソッドが呼び出される変数は変更されません(コピーが呼び出されたメソッドに渡されるため)。ただし、変数全体がコピーされるので、この場合もパフォーマンス上のペナルティが発生する可能性があります。多くの要素を保持するベクトルの場合、これにはかなりの時間がかかります!値渡しは、C++の次のように実現されます。

  • 外部変数も参照渡し時に参照を渡すため、外部変数も変更されます。元の変数と同じ実際のメモリ空間!

    だから、基本的に差が基準でコールを使用した場合、元の呼び出し元の値への参照が渡されている間値コールを使用する場合には、元の呼び出し元の値は、変わらないままであることが何であるかを

この値は両端で変更される可能性があります。

どのような方法が必要なのかは、達成したいものによって決まります。 メソッドに渡す変数が変更されていない場合は、を渡します(例ではm_all_particle_candidates)。または、変更する必要がある場合は、参照/ポインターを渡します。

渡された変数を変更する必要はなく、メソッド内で変数の読み取り専用バージョンのみが必要な場合は、値渡しによって発生する可能性のあるパフォーマンス上の問題を、const参照。しかし、あなたの場合、フルコピー(通常の値渡しを意味する)が必要なようです。

+0

@nyaralthotepああ、constでそれを渡すので、ベクトルの値は変わらないが、アドレスは変わってしまう。私は単にconstとして関数全体を置くことはできないでしょうか? e.x. remove_duplicates(...)const {...}? – MWright

+0

私はもう一度慎重にあなたの質問を読んで、私はconst参照を言及するには時期尚早だったと思う。あなたのケースでは役に立たない(最初のパラメータを除いて)。実際にはコピーが必要です。つまり、2番目のパラメータを値渡しする必要があります。私はそれに応じて私の答えを更新しました – codeling

+0

@nyaralthotepもし私がconst参照を渡す場合、ポインタのベクトルはどのように変更されますか?(私はベクトル消去メソッドを使用するので、const参照はエラーになります)?それゆえ、あなたは値渡しを提案しています – MWright

1

OPのコードはコンパイルされていますか?私はそうは思わない。公平であれば、投稿する前にコンパイラに渡す必要があります。

typedef struct { 
    long double x, y, z; 
} V3; 

void fnExpectingPtrToVec(vector<V3> * pvec) { 
} 

void fnExpectingVec(vector<V3> vec) { 
} 

void testVecs() { 
    vector<V3> v; 
    //fnExpectingPtrToVec(v); Does not compile 
    fnExpectingPtrToVec(&v); 
    fnExpectingVec(v); 
} 

それは第二のparamのベクトルへのポインタを期待している、とあなたは、代わりにベクトルで、そのコンパイルエラーに合格した場合。

ベクトルを受け入れる関数を修正し、それをベクトルで呼び出すと、コピーが作成され、関数を繰り返し呼び出すとm_all_particle_candidatesは変更されません。

関連する問題