2017-07-02 50 views
-3

我正在进行物理项目模拟,我需要计算2个分子的潜力。如何在类型为参数时避免typeid

,这是我认为写代码的一部分:

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

但是,我不能叫他们多态..

+3

这不是C++代码。 – juanchopanza

+0

我将它从C# 转换而来,我需要它在CPP上工作。 但重点不在于它是这个概念的语言。 – pio

+0

有没有强烈的理由,这个问题可以通过继承来解决?您可以将ID分配给不同类型的分子,然后创建一个潜在的2D表格。这将尽可能快。 – geza

回答

1

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

我想,你应该保留分子基础和派生类。您应该在分子类中添加一个ID。并用2个对象的ID进行索引,实现带有2D表格的双重调度。像这样:

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

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