将层次结构向下投射为具体对象
Casting down the hierarchy a concrete object
我正在看一段代码,其中有一个c风格的转换让我感到困惑。
我对cast很熟悉,但是这个我真的不能掌握。这里是:我有两个类,比如说Base和Derived,但是Derived没有添加任何方法/属性。基本上,这只是Base的一个特殊情况,当它的一个属性(称为M_blockSize)被固定为1;但是,这些方法都不需要特定的实现,也没有功能扩展。这种派生类的好处并不是这个线程的重点。让我们假设开发人员有他们这样做的充分理由。
无论如何,在这段代码中,我看起来像这样:
void foo(const Derived& d){...}
[...]
Base b;
foo((Derived&) b);
因此,开发人员将基对象强制转换为对派生对象的引用。在我的理解中,如果"castee"(b)的具体类型确实是派生的,则进行下浇。
然而,这是c风格的强制转换,所以编译器正在尝试一大堆强制转换,我不知道哪一个最终有效。
所以问题:
- 1)编译器在做什么类型转换?我假设是reinterpret_cast ?
- 2)Derived&(b)也能工作吗?
- 3)如果类派生添加了一些方法/属性(未在foo中使用),这还会工作吗?
- 4)的关键点是foo不使用派生的任何功能,是不是已经在基础?
这里生效的强制转换是static_cast<Derived&>
,由以下规则(§5.2.9静态强制转换)控制:
类型的左值" cv1
B
,"B
在哪一个类类型,可以将类型"引用 cv2D
,"D
在哪一个类派生从B
(条款10),如果一个有效的标准从"D
指针"转换到"B指针"的存在(4.10), cv2 cv-qualification一样,或cv-qualification大于 cv1 ,和B
既不是虚拟基类的D
也不是D
虚拟基类的基类。结果类型为"cv2D
."
将"指向D
的指针"强制转换为"指向B
的指针"是一个有效的标准转换(第4.10节):
类型为"指向cv
D
"的右值,其中D
是类类型,可以转换为类型为"指向cvB
"的右值,其中B
是D
的基类(第10条)。
然而,仅仅因为演员阵容有效,并不意味着可以这样做。注意(§5.2.9):
如果类型为"cv1
B
"的对象实际上是类型为D
的对象的子对象,则结果指向类型为D
的封闭对象。否则,强制转换的结果是未定义的。
所以这段代码导致了未定义的行为。可以从基类强制转换到它的任何派生类,但是只有当它确实是派生类型的对象时,才能定义行为。
所以要回答这些问题:
- 这是
static_cast<Derived&>
. - 是的,因为这就是发生的事情。
- 它不工作,因为它导致未定义的行为。 我不能确定这里的重点是什么。如果您在
foo
中不使用任何Derived
特定的功能,我希望它可能继续按预期执行。但是,如果是这种情况,只需采取Base&
。- C++ 提升 - 包含类层次结构对象的类的序列化
- 在C++中将类实例添加到对象层次结构中的问题
- 在访问类的树层次结构中的对象时避免使用 null 指针
- 对象在播放模式下中断层次结构
- 如果对象在同一层次结构中,-Wreturn-std-move clang 警告是否正确
- 命名空间、标头和对象的层次结构
- GCC:当层次结构中存在虚拟继承时,C++11 内联对象初始化(使用 "this")不起作用
- 上对象层次结构
- 层次结构中子类对象的部分构造和销毁
- 在 c++ 中,通常比较继承层次结构中的对象
- 参数化的下一个池对于汇总对象的类层次结构不可能
- 在C++中为游戏对象设计类层次结构
- 谁让狗出去的?- 当"Is-A"在类层次结构中遇到"Has-A"时销毁对象
- 对象层次结构员工程序 - 取消引用 cout 的指针
- OO 正确性 - 继承层次结构 - 谁创建其他对象使用的对象
- 类层次结构中所有对象的静态向量 shared_ptr
- 通过指针在 gdb/Eclipse CDT 调试监视中显示真实的对象层次结构
- 如何使用容器中对象的继承层次结构来维护开放/封闭原则
- 对象层次结构中的对象删除责任
- 对象层次结构"Implementation" - "the easiest way"或如何避免虚拟继承?