避免重复 dynamic_cast 的最佳方法?

Best approach for avoiding repetitive dynamic_cast?

我有这样的情况

Shape *shape =dynamic_cast<Shape*>(obj);

if(dynamic_cast<Rectangle*>(obj))
{
   func();
   Rectangle* obj1 = dynamic_cast<Rectangle*>(obj);
   obj1->DoSomething1();
   obj1->DoSomething2();
}
else if(dynamic_cast<Circle*>(obj))
{
   func();
   Cirlce* obj2 = dynamic_cast<Cirlce*>(obj);
   obj1->DoSomething3();
   obj1->DoSomething4();
}
else if(dynamic_cast<Blah*>(obj))
{
   func();
   Blah* obj1 = dynamic_cast<Blah*>(obj);
   obj1->DoSomething5();
   obj1->DoSomething6();
}
...
...

避免在 if/else 语句中再次调用 dynamic_cast 并为该特定对象类型执行方法的最佳方法是什么?

一般来说,您应该避免此类构造并按照预期的方式利用多态性,例如:

class Shape
{
public:
    virtual void DoSomething() = 0;
};

class Rectangle : public Shape
{
public:
    void DoSomething()
    {
        DoSomething1();
        DoSomething2();
    }
};

class Circle : public Shape
{
public:
    void DoSomething()
    {
        DoSomething3();
        DoSomething4();
    }
};

class Blah : public Shape
{
public:
    void DoSomething()
    {
        DoSomething5();
        DoSomething6();
    }
};

Shape *shape = dynamic_cast<Shape*>(obj);
if (shape)
{
    func();
    shape->DoSomething(); 
}

如果这不是您的代码的选项,您可以执行以下操作以删除重复的 dynamic_cast 调用,至少:

if (Rectangle *r = dynamic_cast<Rectangle*>(obj))
{
    func();
    r->DoSomething();
}
else if (Circle *c = dynamic_cast<Circle*>(obj))
{
    func();
    c->DoSomethingElse();
}
else if (Blah *b = dynamic_cast<Blah*>(obj))
{
    func();
    b->DoSomethingElseElse();
}