我正在进行物理项目模拟,我需要计算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);
但后来我不能称它们为多态......
答案 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);
}
这需要一些手动管理,但解决方案很明确(在我看来),而且速度很快。