void*保留继承信息吗?

jav*_*ver 0 c++ void-pointers static-cast c++14

是否有可能void*保留类型信息?
我试图使它忘记了真正的类型(B*)通过投B* bvoid* v,但它似乎知道它的起源.
这对我来说是好运,但我不知道为什么.

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

我希望c指向B*(一个错误的地址)的地址,但似乎知道这vB*正确的.

它为什么有效?难道void*真的记得类型?
它能"记住"多远?

背景

我试图在这里创建一个void*抽象类,但惊讶它的工作原理. 我想确保它是一个预期的标准行为.

编辑:抱歉新手问题.
现在,我意识到我误解了void*.

Nic*_*las 7

未定义的行为未定义.这意味着无论如何你可能得到"正确答案".

在这种特殊情况下,编译器的布局完全有可能组织起来C,C并且它的基类B具有相同的地址.因此,如果你假装一个是以未定义的方式指向另一个的指针,那么你会得到正确的行为.

今天.明天会发生什么是猜测.

这不是你可以依赖的东西.这只是一个"幸运"的偶然事件.


它是指向C的指针,然后是指向B的指针,然后是指向void的指针,然后是指向C的指针.所有完全合法的转换.

不,他们不是.

它是一个指针C,然后指向B.然后它变成了void*.但标准非常明确:如果将指针转换为a void*,则唯一合法的转换是将其转换为指向从中转换的确切类型的指针.因此,如果您转换B*void*,则唯一的合法转换将返回B*.

不是来自的类型B.

C++ 17将"确切类型"变成"指针可互换类型".但是基类和派生类不是指针可互换的,所以它仍然是UB.

  • @javaLover在`B`之前从`C`继承了非空类. (2认同)