c++ - Casting - 为什么我应该为 Upcasting 做这件事

标签 c++ oop inheritance polymorphism

我一直在阅读该站点上的其他一些主题,他们提到了 dynamic_cast 和 static_cast 是如何安全地进行向上转换的。

为什么向上转换甚至需要这些?

例如,如果类 B 派生自 A,则

A * ptr = new B ();

仍然有效,并且表现得像 A 类型的对象。(我也来自 Java 背景,其中不需要进行向上转换的转换。

我还在这个网站上读到,向下转换不需要 dynamic_cast [有问题的“When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?”] .同样,我认为只有在向下转型时才真正需要转型,因为向上转型是自动发生的。

我哪里错了?

最佳答案

如果您有复杂的继承层次结构,默认的向上转换行为可能不起作用。考虑例如:

struct A {};
struct B : A {};
struct C : A {};
struct D : B, C {};

在该层次结构中,D 类型的对象有两个不同的A 类型的基。从 D*A* 的转换是不明确的。对于这种类型的情况,您可以强制执行中间步骤

A *p = static_cast<B*>(d);   // Give me the 'A' subobject within 'B'

类似地,如果有一个具有多个重载的函数可以采用基类型或派生类型,并且您需要调用采用基类型的版本(注意:这里有代码味道!),那么您可以使用强制转换来指示过载决议。同样,如果您需要直接重载决议,您可能做错了其他事情。

除了极端情况(即当默认向上转换不起作用时),确实没有理由明确使用转换操作,我实际上建议不要这样做,因为转换应该是一个警示灯,过度使用它们可能会使它们正常并且在读取代码时不会发出警报。

关于c++ - Casting - 为什么我应该为 Upcasting 做这件事,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16286023/

相关文章:

python - 静态/动态作用域、类型化、绑定(bind)

Swift 单例子类(继承)

javascript - !important 规则可以用在 IE 的 CSS 表达式中吗?

ruby-on-rails - Rails STI和 "type"字符串的设置

c++ - 关于使用捆绑属性创建 C++ Boost 图

c++ - 从数组指针中添加和减去一个元素

c# - 使用运行时类型(在 C# 中)进行逻辑流

java - 子类是否总是使用父类(super class)的默认构造函数?

c++ - 如何区分来自同一子网和不同 IP/用户的 sockaddr_in 结构

python - 计算两个类实例之间的数值增量