【问题标题】:C++ - std::unique_ptr in vector<> is nullptrC++ - 向量<> 中的 std::unique_ptr 为 nullptr
【发布时间】:2019-02-06 16:34:50
【问题描述】:

我想将Particle 对象存储在vector 对象中,以便以后可以访问它。 这些粒子(ElectronsProtons)继承自Particle 类,该类包含toString() 虚拟方法。然后在 ElectronProton 类中覆盖此 toString() 方法。

当我读取向量容器时,我想访问特定于ElectronProtontoString() 方法,而不是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 对象的指针似乎没问题,但指向ElectronProton 则不行。我猜构造函数有问题?

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

【问题讨论】:

  • 您的代码具有未定义的行为,因为Particle 没有virtual 析构函数。

标签: c++ polymorphism unique-ptr


【解决方案1】:

你犯了一个经典的错误,即使是最有经验的 C++ 程序员也会犯错:你用初始大小声明了向量,然后 push_backed 向它添加了其他元素,而不是分配给现有元素。通过从向量初始化中删除 (nbParticles) 来解决此问题。

【讨论】:

  • 可能想要添加,如果知道会有多少元素,他们应该添加一个调用来保留。这样他们就不必经历多次重新分配。
  • 谢谢,它现在可以工作了 :) 但是为什么 Particleobject 上的指针不是 nullptr 而继承类型上的指针是 nullptr
  • @T0T0R 只是猜测,您将 nbParticles 设置为 1 还是 2?
  • 准确地说,是 int nbElectrons{1};诠释 nbProtons{1}; std::vector<:unique_ptr>> 粒子(nbElectrons+nbProtons);所以是的
  • @zett42 在您知道大小绝对不会过早优化时使用reserve。过早的优化会损害代码的可读性/可维护性或增加代码的复杂性以使代码运行得更快而不衡量它是否需要particles.reserve(3); 提高代码的可读性/可维护性 - 它清楚地传达了“我事先知道这个向量的大小”。没有它,代码会传达关于向量大小的不确定性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-30
  • 2014-03-27
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 2013-09-17
  • 2015-11-28
相关资源
最近更新 更多