2015-04-04 90 views
1

该书The c++ programming language有关于dynamic_cast的部分,我不知道我的理解是否正确。dynamic_casting的对象混淆

dynamic_cast的目的是处理转换的正确性无法由编译器确定的情况。在这种情况下,dynamic_cast(p)查看p指向的对象(如果有的话)。如果该对象属于类T或具有T类型的唯一基类,则dynamic_cast将返回一个类型为T *的指针给该对象;否则,返回nullptr。如果p的值是nullptr,dynamic_cast(p)返回nullptr。请注意,转换必须是唯一标识的对象。可以构造转换失败并返回nullptr的示例,因为p指向的对象具有多个表示类型为T的基类的子对象。

“是否可以构造转换失败的示例,返回nullptr是因为对象指向 to 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 { /* ... */ }; 
为指针的无线电对象的模糊性不是一般的检测在编译时。 这种运行时歧义检测仅适用于虚拟基地。对于普通的基础,当向下转换时(即向派生类;§22.2),总是有一个给定演员(或无)的唯一子对象。虚拟基地的等同含糊性发生在上传(即向基地)时,但这种歧义在编译时被捕获。

我完全不明白这一点。这是什么意思“对于普通的基础,总是有一个特定的演员的独特的子对象”?我知道如果基础不是虚拟的,将为每个从它派生的类创建一个子对象。但就演员而言,我刚刚在上面的例子中造成了一个模棱两可的错误。而“上传时发生虚拟基地的等效歧义”,这是什么意思?虚拟基地可能模棱两可吗?任何人都可以解释清楚吗?

+0

除非您使用'virtual'基础,否则给定'a'只有一个孩子'z'。 – Yakk 2015-04-04 14:33:49

+0

@Yakk 你指的是什么? – morbidCode 2015-04-04 14:53:39

+0

你的课a和z以上? – Yakk 2015-04-04 14:57:35

回答

1

对于普通[非虚拟]碱基,总是有向下转换时(即,向着一个派生类的给定流延(或无)的唯一子对象;§22.2

这是因为非虚拟继承会创建派生类的严格层次结构,而分支不会再次聚集在一起。对象必须是派生类T中的某个派生类,该类派生于该类树的叶节点处。不能再次遇到T,因为一个类不能从它自身继承,因此,动态下降到T,你将最终得到对象的派生类。对于(或每个)继承链中的任何类都是类似的。

+0

那么这句话呢?“上传时虚拟基地的等效歧义发生,但在编译时捕获到这种歧义。”这是什么意思? – morbidCode 2015-04-04 14:50:36

+0

这意味着如果您正在向上注视,从'D&'到'B&',并且有两个或多个类型为'B'的基类,那么在编译时就知道了。在相反的方向上,从'B&'到'D&',在编译时不知道是否有0,1个或更多'D'子对象,因为这取决于当前绑定的对象的最派生类型以供参考。 'dynamic_cast'必须根据编译器发出的类型信息计算出来,并且要么成功,要么给你一个空指针,或者为了引用而抛出一个异常。 – 2015-04-04 16:06:04