【问题标题】:C++ list insertion strange behaviorC++ 列表插入奇怪的行为
【发布时间】:2016-08-19 06:24:27
【问题描述】:

我有一个名为 Particle 的类,还有一个名为 ParticleList 的类,它本质上是一个粒子列表以及一些其他函数。当我尝试将新粒子插入 ParticleList 时,我注意到一些奇怪的行为,我想知道为什么会这样。类定义为:

class Particle {
public:
    // Particle data members
    int index;
    vector<double> r_last;
    vector<double> r;
    vector<double> v;

    double m;
    double q;

    Particle(int i, double m, double q, int ndim) :
            index(i), m(m), q(q) {
        r_last.resize(ndim,0);
        r.resize(ndim,0);
        v.resize(ndim,0);};

    Particle() { };
    Particle(const Particle& p);
}

class ParticleList : public list<Particle> {
public:
    int highestIndex;
    size_t numParticles;
    ParticleList() {highestIndex = 0; numParticles=0;}


      /*below are functions that call the List<Particle>::push_back() 
      and List<Particle>::push_front() functions and increment numParticles*/

   void push_back(const Particle& p);
   void push_front(const Particle& p);

   //some more member functions here

};

push_back和push_front的定义:

void ParticleList::push_back(const Particle &p) {
    numParticles ++;
    list<Particle>::push_back(p);
}

void ParticleList::push_front(const Particle &p) {
    numParticles ++;
    list<Particle>::push_front(p);
}

当我尝试如下插入一个粒子时,问题就来了:

    ParticleList newParticleList;
    Particle newParticle(1, 0.5, 0.5, 2); 
    /*creates a particle with index 1, mass and charge 0.5, and 2 dimensions. 
Variables r, r_last and v are set to vectors {0,0}*/

    for (int i=0;i<nDim;i++)
        newParticle.r[i]=0.5 //just changed newParticle.r, everything else still {0,0}

    newParticleList.push_back(newParticle);

由于某种原因,当我执行最后一步时,刚刚插入的列表成员的 r_last 向量的值更改为 r 向量的值。因此,如果我打印出 newParticle.r_last,那会给我 {0,0},但如果打印出列表的成员:

auto ii=newParticleList.end();
ii--;
Particle p=*ii;
for(int i=0;i<p.size();i++)
    cout<<p.r_last[i];

我得到 {0.5,0.5},这是 p.r. 的值。如果我在此之后更改 r 向量,它不会影响 r_last 的值......只有当我 push_back 时它才会产生这种效果。我尝试了不同的计算机,删除了优化标志,尝试了 push_front 和 insert,但它仍然是相同的行为。有没有人知道可能导致这种情况的原因?

谢谢!

悉达多

【问题讨论】:

  • 一般建议:不要从没有虚拟析构函数的类型派生,std 的大多数类型都是这种情况。
  • 您设置了Particle.r,但您打印了Particle.r_last,我们不知道这两者之间的联系。我们也不知道push_back 的实现(它可能没有像你那样声明,因为它需要一个参数...),在push_back 中可能有一个Particle 的复制构造函数,但你没有显示其实施。通过默认复制构造函数,使ParticleList::push_back 仅使用const Particle&amp; 调用list::push_back 并打印r 而不是r_back,代码有效,因此请提供MCVE
  • 最诚挚的歉意,我在push_back和push_front的声明中打错了。它将对粒子的引用作为参数。我现在已经更正了,并添加了这两个函数的定义。
  • @SiddharthKrishnamoorthy 我很确定问题来自Particle 的复制构造函数 - 如果使用默认的 (Particle(const Particle&amp; p) = default;),你会得到什么?
  • 确实,刚刚检查了复制构造函数,并且 p.r 被复制到 r_last 中。感谢您的帮助!

标签: c++ list class oop


【解决方案1】:

在这里Particle p=*ii; 创建Particle 对象的副本。所以检查你的复制构造函数Particle(const Particle&amp; p);。可能是它错误地将p.r 复制到p.r_last

【讨论】:

  • 哇哦。发现!事实上,我改变了它现在可以工作。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
相关资源
最近更新 更多