我试图删除一个指针向量,我将值传递给某个函数。我通过值传递的原因是我计划在对函数的多次调用中擦除这些值。所以,如果我通过指针/引用传递,我无法实现这一点。
首先是上述陈述是正确的吗?
以下是一些示例代码:
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 :(得分: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
类型,您可能需要覆盖Particle
和POD
的虚拟析构函数,复制构造函数和赋值运算符。