dynamic_casting 对象混淆

dynamic_casting of objects confusion

本书 The c++ programming language 中有关于 dynamic_cast 的章节,我不确定自己是否理解正确。

The purpose of dynamic_cast is to deal with the case in which the correctness of the conversion cannot be determined by the compiler. In that case, dynamic_cast(p) looks at the object pointed to by p (if any). If that object is of class T or has a unique base class of type T, then dynamic_cast returns a pointer of type T* to that object; otherwise, nullptr is returned. If the value of p is nullptr, dynamic_cast(p) returns nullptr. Note the requirement that the conversion must be to a uniquely identified object. It is possible to construct examples where the conversion fails and nullptr is returned because the object pointed to by p has more than one subobject representing bases of type T.

是否可以构建转换失败并返回 nullptr 的示例,因为对象指向 to by p 有多个子对象表示类型 T 的基”是什么意思?

class a {
public:
    a() { }
};

class b : public a {
public:
    b() { }
};

class z : public a, public b {
public:
    z() { }
};

void f(z* p) {
    a* x = dynamic_cast<a*>(p); // ambiguous
}

还有一个,这是摘自书上的:

class Component : public virtual Storable { /* ... */ };
class Receiver : public Component { /* ... */ };
class Transmitter : public Component { /* ... */ };
class Radio : public Receiver, public Transmitter { /* ... */ };
The ambiguity for a pointer to a Radio object is not in general detectable at compile time. This kind of run-time ambiguity detection is needed only for virtual bases. For ordinary bases, there is always a unique subobject of a given cast (or none) when downcasting (that is, toward a derived class; §22.2). The equivalent ambiguity for virtual bases occurs when upcasting (that is, toward a base), but such ambiguities are caught at compile time.

我完全不明白这一点。 "For ordinary bases, there is always a unique subobject of a given cast" 是什么意思?我知道如果基础不是虚拟的,将为每个从它派生的 class 创建一个子对象。但就转换而言,我只是在上面的例子中造成了歧义错误。还有 "The equivalent ambiguity for virtual bases occurs when upcasting",那是什么意思?虚拟基地可以模棱两可吗?谁能解释得更清楚?

For ordinary [non-virtual] bases, there is always a unique subobject of a given cast (or none) when downcasting (that is, toward a derived class; §22.2

那是因为非虚拟继承创建了派生的 classes 的严格层次结构,分支不会再次聚集在一起。一个对象必须是某个最派生的 class T,在 classes 的那棵树的叶节点下。往上走,就不能再遇到T了,因为一个class是不能继承自己的。因此,通过向下到 T 的动态转换,您将最终得到对象的最派生 class。并且对于(或每个)继承链中的任何 class 也是类似的。