传递一个指针矢量和擦除副本

时间:2012-01-05 14:58:58

标签: c++

我试图删除一个指针向量,我将值传递给某个函数。我通过值传递的原因是我计划在对函数的多次调用中擦除这些值。所以,如果我通过指针/引用传递,我无法实现这一点。

首先是上述陈述是正确的吗?

以下是一些示例代码:

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函数中存在拼写错误。我通过指针传递而不是值。它应该是值

3 个答案:

答案 0 :(得分:1)

我对你所说的关于通过价值和通过引用传递的内容感到有点困惑,所以我将首先给出一个简短的解释:

  • 通过值传递时,调用方法的变量保持不变(因为副本传递给被调用的方法)。但要小心,这种情况也会导致严重的性能损失,因为整个变量都被复制了!如果向量包含许多元素,这可能需要相当长的时间!在C ++中实现了这样的传递:

  • 当通过引用传递(或者更多或更少等价于指针)时,外部变量也会更改 - 因为您只是将引用传递给方法,该方法引用内存中与原始相同的实际空间可变!

所以基本上不同的是,当使用按值调用时,原始调用者的值保持不变,而使用按引用调用时 >,传入对原始调用者值的引用,因此该值可以在两端发生更改。

现在需要哪种方法只取决于你想要达到的目标。如果您传入方法的变量应保持不变(<{1}},则按值传递。或者,如果您需要更改,则通过引用/指针传递。

如果传入的变量不应该更改,但是您在方法中只需要变量的只读版本,那么通过使用可以克服通过传递值引入的可能的性能问题const参考。但是,在您的情况下,您似乎需要一个完整的副本(意味着正常的值传递)。

答案 1 :(得分: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);
}

如果期望在第二个参数中指向一个向量的指针,而你传入一个向量,那么它就是编译错误。

当您修复函数以接受向量而不是指向向量的函数,并使用向量调用它时,它将复制并且对函数的重复调用将使m_all_particle_candidates保持不变。

答案 2 :(得分: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);

但这样做时要小心。将进行复制,因此如果它们不是Boson类型,您可能需要覆盖ParticlePOD的虚拟析构函数,复制构造函数和赋值运算符。