[英]Why is dynamic_cast evil or not ? Should I use dynamic_cast in this case?
Some say the use of dynamic_cast often means bad design and dynamic_cast can be replaced by virtual functions
有人说the use of dynamic_cast often means bad design and dynamic_cast can be replaced by virtual functions
dynamic_cast
considered bad design? 为什么使用dynamic_cast
认为设计不好? Suppose I have I function name func(Animal* animal, int animalType)
, the implementation in func is like: 假设我有函数名称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. */ }
Is this case a proper use of dynamic_cast
? 这种情况是否正确使用了dynamic_cast
?
This is EXACTLY the wrong place to use dynamic_cast
. 这完全是使用dynamic_cast
的错误位置。 You should be using polymorphism. 你应该使用多态。 Each of the Animal
classes should have a virtual
function, say, process
and here you should just call animal->process()
. 每个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(); }
}
Other problems. 其他问题。
What if animal
is a Dog
, but due to a bug animal_type
says its a Cat
? 如果animal
是一只Dog
怎么办,但由于虫虫animal_type
说它是一只Cat
?
There are times when static_cast
is necessary, and if possible use it instead of dynamic_cast
. 有时需要static_cast
,如果可能的话,使用dynamic_cast
而不是dynamic_cast
。 Dynamic cast has the additional performance cost that static cast does not. 动态强制转换具有静态强制转换所不具备的额外性能成本。 For this, you need to be sure you know the type that is coming in, since static_cast
is more unsafe. 为此,您需要确保知道正在进入的类型,因为static_cast
更不安全。
At the very least, animal_type
should be a member of Animal
. 最起码, animal_type
应的成员Animal
。
In theory, down-casting should never be necessary. 从理论上讲,永远不需要进行压铸。 Instead you should adapt the base class to include the necessary virtual
method. 相反,您应该调整基类以包含必要的virtual
方法。
In practice, you encounter things such as 3rd party libraries. 在实践中,您会遇到第三方库等问题。 In this case, modifying the base class is not an option and thus you may be forced into using dynamic_cast
... 在这种情况下,修改基类不是一个选项,因此您可能被迫使用dynamic_cast
...
Back to your example: 回到你的例子:
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
And then: 然后:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.