当类型为参数时,如何避免使用typeid

时间:2017-07-02 22:43:25

标签: c++ oop polymorphism typeid

我正在进行物理项目模拟,我需要计算2个分子的潜力。

这是我想写的代码的一部分:

class Molecule
{
    public:
    double someBulshit;
    virutal double Potential(const Molecule & mol);
}

class LC : public Molecule
{
    public:
    virtual double Potential(const Molecule & mol)
    {
        if(typeid(mol) ==typeid(LC))
            return 1;// for the example
        return 3;
    }

}
class Col : public Molecule
{
    public:
    virtual double Potential(Molecule mol)
    {
        if (typeid(mol) == typeid(Col))
            return 2;
        return 3;
    }
}

    int main(int argc, char* argv[])
    {
        Molecule mol1 = new Col();
        Molecule mol2 = new LC();

        double my_potential = mol1.Potential(mol2);
        printf ("%f",my_potential); 
    }

我听说使用typeid很糟糕,但我无法在不使用它的情况下找到另一种方法。 这也是性能敏感和typeid我明白不建议使用typeid。

我试图分成不同的功能:

double Potential(const LC & mol);
double Potential(const Col & mol);

但后来我不能称它们为多态......

1 个答案:

答案 0 :(得分:1)

您需要某种双重发送。这里通常的建议是Visitor Pattern。但是,在这种情况下我不推荐它。

我认为,你应该保留Molecule基础和派生类。您应该在Molecule类中添加一个ID。并使用2D对象实现双重调度,由2个对象的ID索引。像这样:

class Molecule {
  private:
    int m_id;
  public:
    Molecule(int id) : m_id(id) { }

    int id() const {
      return m_id;
    }
};

class LC: public Molecule {
  private:
    // members here
  public:
    LC() : Molecule(0) { }
};

class Col: public Molecule {
  private:
    // members here
  public:
    Col() : Molecule(1) { }
};

double potential_lc_vs_lc(const Molecule &a, const Molecule &b) {
  const LC &lc_a = static_cast<LC &>(a);
  const LC &lc_b = static_cast<LC &>(b);
  // calculate potential LC (lc_a) vs LC (lc_b) here
  return ...;
}

// all the potential_XX_vs_XX functions come here

const double (*potentialCalculatorTable[2][2])(const Molecule &, const Molecule &) = { { potential_lc_vs_lc, potential_lc_vs_col }, ... };

double calculatePotential(const Molecule &a, const Molecule &b) {
  return (*potentialCalculatorTable[a.id()][b.id()])(a, b);
}

这需要一些手动管理,但解决方案很明确(在我看来),而且速度很快。