当类型是参数时如何避免typeid

How to avoid typeid when the type is argument

我正在做一个物理项目模拟,我需要计算 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);

但是我不能称它们为多态的..

你需要某种双重调度。这里通常推荐的是Visitor Pattern。但是,我不推荐这种情况。

我认为,您应该保留分子基础和派生的 classes。您应该在 Molecule class 中添加一个 ID。并使用 2D table 实现双重分派,由 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);
}

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