Casting -为什么我应该为Upcasting做这个
Casting - Why Should I do it for Upcasting
我一直在阅读这个网站上的其他一些帖子,他们提到dynamic_cast和static_cast对于上行转换都是安全的。
为什么需要这些来进行向上转换?
例如,如果类B派生自类A,则
A * ptr = new B ();
仍然可以工作,并且表现得像a类型的对象(我也是来自Java背景,不需要进行上转换的转换)。
我还在这个网站上读到dynamic_cast不需要向下转换[在问题"何时应该使用static_cast, dynamic_cast, const_cast和reinterpret_cast ?"]. 再一次,我认为只有当你向下转换时才真正需要转换,因为向上转换是自动发生的。
我错在哪里?
如果您有复杂的继承层次结构,默认的向上转换行为可能不起作用。例如:
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'
类似地,如果有一个函数具有多个重载,可以采用基类型或派生类型,并且需要调用采用基类型的版本(注意:这里有代码气味!),那么可以使用强制类型转换来直接重载解析。同样,如果您需要直接重载解析,那么您可能在其他地方做错了。
除了极端情况(即当默认的向上转换不起作用时),真的没有理由显式地使用强制转换操作,我实际上不建议这样做,因为强制转换应该是一个警示灯,过度使用它们可能会使它们正常并且在读取代码时不会发出警报。
在多重继承的情况下(Java实际上没有),您可能会调整您的"this"指针。在这种情况下,reinterpret_cast是不安全的,这就是他们试图通过说static_cast和dynamic_cast是安全的来强调的。
作为一个小提示,在对一个要移植到Android-without-dynamic_cast的代码库的调查中,我发现了127个dynamic_cast,其中122个实际上是不必要的。
为什么需要这些来进行向上转换?
它们不是,并且将它们用于向上强制转换(IMHO)是误导:不需要强制转换是有原因的:逻辑上,子类对象是超类的实例。
总之,我不鼓励显式向上转换。对于坚持这一点的人,我至少要求一致性:在的任何地方使用显式的向上转换,包括初始化:
A * ptr{static_cast<A*>(new B)};
大多数人会认为这很愚蠢。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在全局范围内使用"extern int a"似乎不行?
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 为什么会发生堆损坏
- 为什么使用 "this" 指针调用派生成员函数?
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么比较运算符如此快速
- 为什么 Serial.println(<char[]>);返回随机字符?
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 为什么不;名字在地图上是按顺序排列的吗
- 我的字符计数代码计算错误.为什么
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 为什么 std::unique 不调用 std::sort?
- 既然存在危险,为什么项目要使用-I include开关
- Casting -为什么我应该为Upcasting做这个