隐式转换 vs. static_cast 在向上转型时的区别

11

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

因此,B和C从A继承(公共继承)。 我有一个指向A的指针列表,我用B或C的指针填充它。

问题是:在进行转换时,哪种样式更受青睐?

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 更容易搜索,但在这种情况下,隐式转换应该已足够。

2个回答

12

你不必对基类进行 static_caststatic_cast 是为了反向转换。所以这样做是可以的。

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

你需要使用static_cast的时候是将基类A*转换为派生类B*
B* some_obj = static_cast<B*>(myList.front());

这就是我需要的答案。所以在向上转换时不需要使用static_cast,但在向下转换时需要使用。谢谢!(而且回答非常迅速!) - fern17
2
@fern17 还有,需要注意的是,在向下转型时,你可能并不总是知道它是 B 还是 C。这就是 dynamic_cast 的作用。 - JorenHeit
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - fern17

1
我希望在已提供的答案基础上提供一个非常通用的解决方案。
永远不要明确地转换编译器已经为您隐式转换的内容。
我们甚至可以进一步概括:
人会犯错误。永远不要明确地执行编译器已经为您执行的操作。
...虽然在某些非常模糊的特殊情况下这可能更具争议。前面的句子应始终成立。
明确地进行超额转换只是违反了DRY原则,更重要的是,在未来会引起人为错误和混淆。
因此,避免明确转换任何不需要的内容。显式转换是一种武器:如果过于频繁地使用它们,某人肯定会受到伤害。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接