C ++ - std :: unique_ptr в векторе <> равно nullptr - PullRequest
0 голосов
/ 31 августа 2018

Я хочу хранить Particle объекты в vector объекте, чтобы я мог получить к нему доступ позже. Эти частицы (Electrons и Protons) наследуются от класса Particle, который содержит виртуальный метод toString(). Этот метод toString() затем переопределяется в классах Electron и Proton.

Когда я читаю векторный контейнер, я хочу получить доступ к методу toString(), специфичному для Electron или Proton, а не к Particle.

По-видимому, одним из способов является использование std::unique_ptr. Вот часть кода, которую я пытаюсь запустить:

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
    /**/
}

Указатель на Particle объект выглядит нормально, но не на Electron или Proton. Я думаю, что-то не так с конструкторами?

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;
}

и определения:

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){}

1 Ответ

0 голосов
/ 31 августа 2018

Вы допустили классическую ошибку, которая сбивает с толку даже самых опытных программистов на C ++: вы объявили вектор с начальным размером, а затем push_back добавили к нему дополнительные элементы вместо присвоения существующим элементам. Исправьте это, удалив (nbParticles) из векторной инициализации.

...