代码之家  ›  专栏  ›  技术社区  ›  pio

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

  •  -3
  • pio  · 技术社区  · 7 年前

    我正在做一个物理项目模拟,我需要计算两个分子的势能。

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

    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不推荐与它一起使用。

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

    1 回复  |  直到 7 年前
        1
  •  1
  •   geza    7 年前

    你需要某种 双重调度 Visitor Pattern

    我认为,你应该保留分子基和派生类。你应该在分子类中添加一个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);
    }
    

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

    推荐文章