无效*保留继承信息

Does void* reserve inheritance information?

本文关键字:信息 继承 保留 无效      更新时间:2023-10-16

void*可以保持类型信息吗?
我试图使它忘记B* bvoid* v的真实类型(B*(,但它似乎知道其起源。
这对我来说是个好人,但我不知道为什么。

这是一个简化的代码(完整演示(: -

#include <iostream>
#include <memory>
using namespace std;
class B{public: int ib=1;};
class C:public B{public: int ic=2;};
int main() {
    B* b=new C();
    void* v=b;                     //<- now you forget it!
    C* c=static_cast<C*>(v);    
    std::cout<<c->ib<<" "<<c->ic<<std::endl; //print 1 and 2 correct (it should not)
    return 0;
}

我希望c指向B*的地址(一个错误的地址(,但似乎知道vB*并正确施放。

问题

为什么起作用?void*真的记得类型吗?
它可以"记住"多远?

背景

我试图在这里创建一个void*抽象类,但惊讶于它有效。
我想确保这是一种预期的标准行为。

编辑:对不起新手问题。
现在,我意识到我误解了void*

未定义的行为是不确定的。这意味着您可能会可能,无论如何得到"正确的答案"。

在这种特殊情况下,编译器的布局完全有可能组织C,从而使C及其基类B具有相同的地址。因此,如果您以不确定的方式假装一个指向另一个指针,则会得到正确的行为。

今天。明天发生的事情是猜测的问题。

这不是您可以依靠的。这只是一个"幸运的"偶然性。


这是指向C的指针,然后是指向B的指针,然后是指向void的指针,然后是指向C的指针。所有完美的法律转换。

不,他们不是。

这是C的指针,然后是B的指针。然后它成为void*。但是标准很清楚:如果将指针转换为void*,则仅法律转换是将其转换为指针转换为的确切类型,该类型是从。因此,如果您从B*转换为void*,则唯一的法律转换回到B*

不是从B派生的类型。

c 17将"确切类型"变成"指针互连类型"。但是基本和派生的类是不是 pointer-Interconvertconvertable,所以它仍然是UB。

(尼科尔是正确的;我的答案是更多的入门级,并且不会进入语言律法;但是,您还应该发现它足够与现实中的观察值相匹配。(


我希望C指向B*

的地址

它做到了。

(一个错误的地址(

不,这是正确的地址。

,但似乎知道V是B*并正确施放的。

它知道每个C都有B基数。因为这就是C的定义。

因此,C*指向带有一些B东西的内存区域,然后是一些C东西。

您的void*一无所获;所有这些"智能"都在于BC的定义。