I want to store Particle objects in a vector object, so I can access it later.
These particles (Electrons and Protons) are inherited from the Particle class which contains a toString() virtual method. This toString() method is then overrided in Electron and Proton classes.
When I read the vector container, I want to access to the toString() method specific to Electron or Proton, and not to Particle.
Apparently, one way is to use std::unique_ptr. Here is the part of the code I try to run:
int main(){
    /**/
    std::vector<std::unique_ptr<Particle>> particles(nbParticles);
    particles.push_back(std::unique_ptr<Electron>( new Electron(1.0, 2.0, 3.0)));
    particles.push_back(std::unique_ptr<Proton>(new Proton(1.0, 2.0, 3.0)));
    particles.push_back(std::unique_ptr<Particle>(new Particle(0.0, 0.0, 1.0, 2.0, 3.0)));
    if (particles[0]==nullptr){
        std::cout<< "index=0 : nullptr"<<std::endl; //There is a null_ptr at particles[0]
    }
    if (particles[2]==nullptr){
        std::cout<< "index=2 : nullptr"<<std::endl; //There is not a null_ptr at particles[2]
    }
    std::cout<<particles[0]->toString()<<std::endl; //This is what I'm trying to do
    /**/
}
A pointer to a Particle object seems to be fine, but not to an Electron or Proton. I guess there is something wrong with the constructors ?
class Particle
{
public:
    Particle();
    Particle(double mass, double charge, double posX, double posY, double posZ);
    virtual std::string toString() const;
}
class Electron : public Particle
{
public:
    Electron(double PosX, double PosY, double PosZ);
    virtual std::string toString() const;
}
class Proton : public Particle
{
public:
    Proton(double PosX, double PosY, double PosZ);
    virtual std::string toString() const;
}
and the definitions:
Particle::Particle(double mass, double charge, double posX, double posY, double posZ) :
    m_mass(mass), m_charge(charge),
    m_posX(posX), m_posY(posY), m_posZ(posZ) {}
Electron::Electron(double PosX, double PosY, double PosZ) :
    Particle(9.109E-31, -1.602E-19, PosX, PosY, PosZ){}
Proton::Proton(double PosX, double PosY, double PosZ) :
    Particle(9.109E-31, +1.602E-19, PosX, PosY, PosZ){}
                It will work. unique_ptr& operator=(nullptr_t) noexcept ; Effects: reset() .
> class unique_ptr<T[], Deleter>; (2) (since C++11) std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope.
std::unique_ptr::unique_ptr default constructor (1), and (2) The object is empty (owns nothing), with value-initialized stored pointer and stored deleter.
Yes, you can compare it to nullptr after the move and it is guaranteed to compare equal. This is clearly true after calling release().
You've made a classic mistake that trips up even the most experienced C++ programmers: you declared the vector with an initial size and then push_backed additional elements to it instead of assigning to the existing elements. Fix this by removing the (nbParticles) from the vector initialization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With