当涉及虚拟继承时,为什么static_cast不能用于downcast? [英] Why can't static_cast be used to down-cast when virtual inheritance is involved?

查看:127
本文介绍了当涉及虚拟继承时,为什么static_cast不能用于downcast?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码:

struct Base {};
struct Derived : public virtual Base {};

void f()
{
    Base* b = new Derived;
    Derived* d = static_cast<Derived*>(b);
}

这是标准禁止的( [n3290: 5.2.9 / 2] )所以代码不能编译,因为派生 虚拟继承自 Base 。从继承中删除 virtual 会使代码有效。

This is prohibited by the standard ([n3290: 5.2.9/2]) so the code does not compile, because Derived virtually inherits from Base. Removing the virtual from the inheritance makes the code valid.

此规则存在的技术原因是什么? / p>

What's the technical reason for this rule to exist?

推荐答案

技术问题是没有办法从一个 Base * Base 子对象的开始和 Derived 对象的开始之间的偏移量。

The technical problem is that there's no way to work out from a Base* what the offset is between the start of the Base sub-object and the start of the Derived object.

在您的示例中,它显示为OK,因为只有一个类可以看到 Base 似乎不相关的继承是虚拟的。但是编译器不知道是否有人定义另一个类Derived2:public virtual Base,public Derived {} ,并且正在投射 Base * code>指向 Base 子对象。一般来说[*], Base 子对象和派生子对象之间的偏移 Derived2 可能与 Base 子对象和完整的派生对象之间的偏移量不同因为 Base 实际上是继承的。

In your example it appears OK, because there's only one class in sight with a Base base, and so it appears irrelevant that the inheritance is virtual. But the compiler doesn't know whether someone defined another class Derived2 : public virtual Base, public Derived {}, and is casting a Base* pointing at the Base subobject of that. In general[*], the offset between the Base subobject and the Derived subobject within Derived2 might not be the same as the offset between the Base subobject and the complete Derived object of an object whose most-derived type is Derived, precisely because Base is virtually inherited.

因此,没有办法知道完整对象的动态类型,以及你给出的指针和要求的结果之间的不同偏移,取决于动态类型。因此,转换是不可能的。

So there's no way to know the dynamic type of the complete object, and different offsets between the pointer you've given the cast, and the required result, depending what that dynamic type is. Hence the cast is impossible.

您的基本没有虚拟函数,因此没有RTTI,所以肯定没有方式来告诉完整对象的类型。即使 Base 确实有RTTI(我不立即知道为什么),但是我猜测没有检查一个 dynamic_cast 在这种情况下是可能的。

Your Base has no virtual functions and hence no RTTI, so there certainly is no way to tell the type of the complete object. The cast is still banned even if Base does have RTTI (I don't immediately know why), but I guess without checking that a dynamic_cast is possible in that case.

[*]我的意思是,如果这个例子不证明点,然后继续添加更多的虚拟继承,直到您会发现偏移量不同的情况; - )

[*] by which I mean, if this example doesn't prove the point then keep adding more virtual inheritance until you find a case where the offsets are different ;-)

这篇关于当涉及虚拟继承时,为什么static_cast不能用于downcast?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆