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_back
ed 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