9

有人说the use of dynamic_cast often means bad design and dynamic_cast can be replaced by virtual functions

  1. 为什么使用被dynamic_cast认为是糟糕的设计?
  2. 假设我有 I function name func(Animal* animal, int animalType), func 中的实现如下:

    bool func(Animal* animal, int animalType)
    {
      ...
      /* Animal is the base class of Bear, Panda, Fish ....
      dynamic_cast animal to real animals(Bear, Panda, Fish...) 
      according to animalType. Do some processing with this specific
      type of animal, using its additional information beyond base 
      class Animal. */
    }
    

这种情况是否正确使用dynamic_cast

4

3 回答 3

18

这是完全错误的地方使用dynamic_cast。您应该使用多态性。每个Animal类都应该有一个virtual函数,比如说,process在这里你应该只调用animal->process().

class Animal {
    virtual void Process() = 0;
}

class Cat : public Animal {
    void Process() { std::cout << " I am a tiny cat"; }
}

class Bear : public Animal {
    void Process() { std::cout << "I am a big bear"; }
}

void func(Animal * animal) {
    if (animal != nullptr) { animal->Process(); }
}

其他问题。

如果animal是 a Dog,但由于一个错误animal_type说它是 aCat怎么办?

有些时候static_cast是必要的,如果可能的话,用它来代替dynamic_cast. 动态转换具有静态转换没有的额外性能成本。为此,您需要确保知道传入的类型,因为static_cast它更不安全。

至少,应该.animal_typeAnimal

于 2013-08-26T08:04:40.770 回答
4

从理论上讲,永远不需要向下转换。相反,您应该调整基类以包含必要的virtual方法。

在实践中,您会遇到诸如 3rd 方库之类的东西。在这种情况下,修改基类不是一种选择,因此您可能被迫使用dynamic_cast...

回到你的例子:

class Animal {
public:
    // starts moving toward `p`,
    // throws a `Unreachable` exception if `p` cannot be reached at the moment.
    virtual void moveToward(Point const& p) = 0;
}; // class Animal

接着:

bool move(Animal& animal, Point const& p) {
    try {
        animal.moveToward(p);
        return true;
    } catch (Unreachable const& e) {
        LOG(animal.id() << " cannot reach " << p << ": " << e.what());
    }

    return false;
} // move
于 2013-08-26T08:55:40.020 回答
0

当您使用向下转换时,dynamic_cast 很好,因为它限制您向下转换为不相关的类型。请参考这个

于 2013-08-26T08:13:55.300 回答