向上转换时的隐式转换与 static_cast

Implicit conversion vs. static_cast when upcasting

假设我有三个类:A(母亲,抽象),B和C,A的children。

所以B和C继承自A(public继承)。 我有一个指向 A 的指针列表,我用 B 或 C 的指针填充它。

问题是:casting/conversion 时首选哪种风格?

class A {};
class B : public A {};
class C : public A {};

B* objB = new B();
C* objC = new C();

std::list<A*> myList;
// Option A: static cast conversion
myList.push_back(static_cast<A*> (objB));
myList.push_back(static_cast<A*> (objC));

// Option B: implicit conversion
myList.push_back(objB);
myList.push_back(objC);

// Option C: C-style conversion (I understand that this is evil and must be avoided)
myList.push_back((A*) objB);
myList.push_back((A*) objC);

那么,就清晰度(代码风格)和安全性而言,哪个更好?我知道 static_cast 更容易搜索,但在这种情况下,隐式转换就足够了。

不一定要static_cast到基地class,static_cast是往另一个方向走。所以这很好

myList.push_back(objB);
myList.push_back(objC);

你必须 static_cast 的时间是将 A* 转换为派生的 class B*

B* some_obj = static_cast<B*>(myList.front());

我想用一个非常通用的解决方案扩展已经提供的答案。

永远不要显式转换编译器已经为您隐式转换的内容。

我们甚至可以将其进一步概括为:

人都会犯错。永远不要明确地做编译器已经为你做的事情。

...尽管在一些非常晦涩的例外情况下这可能更值得商榷。上一句应该始终成立。

显式地过度转换只是违反了 DRY 原则,更重要的是,将来会引发人为错误和混乱。

因此,请避免显式转换任何不需要它的内容。明确的转换是一种武器:不必要地过于频繁地炫耀它们,并且有人一定会受伤。