dynamic_cast 的实现依赖于 RTTI,所以总是让人觉得它性能不行,使用这个东西多半会有一种犯了大忌的感受。 1、如果继承关系比较简单,比如 rectangle、circle 派生自 shape,只有两层,那么可以使用 variant 来代替虚函数多态。using shape = std::variant; 当需要 downcast 的时候,可以直接从variant的index来查询当前实际的对象,使用get_if来进行转型。 实际上,在这种简单的场景下,dynamic_cast的性能也并不差,虚表中有记录偏移量,我怀疑使用dynamic_cast进行转型应该和variant是差不多的。 2、 如果继承关系比较复杂,variant可能无法适应这样的场景,只好使用传统虚函数多态。如果需要用到dynamic_cast,那么貌似 visitor 模式可以消除掉这种可能,比如:struct Visitor; struct West { virtual void accept(Visitor &visitor) = 0; // ... }; struct Lebrun; struct Bronny; struct Visitor { virtual void visit(Lebrun &d) = 0; virtual void visit(Bronny &d) = 0; }; struct Lebrun : public West { void accept(Visitor &visitor) override { visitor.visit(*this); } // ... }; struct Bronny : public Lebrun { void accept(Visitor &visitor) override { visitor.visit(*this); } void enhanced_Wade() { println("不认同裙带关系的,都是底层思维!"); } // ... }; struct WinARealRing : public Visitor { void visit(Lebrun &gOat) override { throw std::runtime_error("没这个能力,知道吧?"); } void visit(Bronny &grandsan) override { grandsan.enhanced_Wade(); } }; int main() { West *p = new Bronny; WinARealRing visitor; p->accept(visitor); // ... return 0; } 这里利用双重分发来回避了 dynamic_cast。 3、基于 2,貌似大部分 downcast 场景都可以使用 Visitor 模式来回避 dynamic_cast;至于 sidecast,本来就是个冷门知识点,很多人都还不知道呢,可见其使用场景更加稀少。 那么问题来了,你在什么情况下非得使用 dynamic_cast 不可?