动态转换规范规则说明

问题描述

我们有 dynamic_cast 的一般形式:

dynamic_cast (表达式)

我对这条规则 (5a) 的粗体部分感到特别困惑:

5:如果表达式是指向多态类型 Base 的指针或引用, 并且 new-type 是指向运行时派生的类型的指针或引用 执行检查:

a) 表达式指向/标识的最派生的对象是 审查。如果在该对象中,表达式指向/引用公共 派生的基础,并且如果只有一个派生类型的对象被派生 从表达式指向/标识的子对象,然后结果 施法点/指的是派生对象。 (这被称为 “垂头丧气”。)

请举例说明这部分不满足的地方?

以上摘录来自 cppreference:cppreferenc

解决方法

充实多继承示例@Peter 总结:

     Base1
     /   \  <-- Virtual inheritance here
  Base2  Base2
    |     | <-- Nonvirtual inheritance here and below
  Left   Right
    \     /
    Derived

Base1* p_base1 = new Derived();
Base2* p_base2 = dynamic_cast<Base2*>(p_base1); // Which Base2?

在一个 Base2 对象中有两个不同的 Derived 对象,那么 p_base2 应该指向哪一个?

代码示例:

#include <iostream>

struct Base1 { virtual ~Base1() = default; };
struct Base2 : virtual Base1 { };
struct Left : Base2 { };
struct Right : Base2 { };
struct Derived : Left,Right {
    Derived() : Base1() {}
};

int main()
{
    Base1* p_base1 = new Derived();
    Base2* p_base2 = dynamic_cast<Base2*>(p_base1);
    std::cout << std::boolalpha;
    std::cout << "p_base1 == nullptr: " << (p_base1 == nullptr) << '\n';
    std::cout << "p_base2 == nullptr: " << (p_base2 == nullptr);
    delete p_base1;
}

这里要小心一点:Base1 是虚拟继承的,因此只有一个 Base1 子对象,我们实际上可以初始化 p_base1。但是,Derived 非虚拟地从 LeftRight 继承,这意味着它有两个 Base2 实例。因此,向下转型失败了。

输出:

p_base1 == nullptr: false
p_base2 == nullptr: true

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...