【发布时间】:2017-04-20 14:08:53
【问题描述】:
void* 是否有可能保留类型信息?
我试图通过将B* b 转换为void* v 使其忘记真正的类型(B*),但它似乎知道它的起源。
这对我来说是好运,但我不知道为什么。
这是一个简化的代码 (full demo) :-
#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* 的地址(地址错误),但它似乎知道v 是B* 并正确转换。
问题
为什么有效? void* 真的记得类型吗?
它能“记住”多远?
背景
我正在尝试创建一个 void* 抽象类 here,但很惊讶它可以工作。
我想确保这是预期的标准行为。
编辑:很抱歉这个新手问题。
现在,我意识到我误解了void*。
【问题讨论】:
-
通过使用
static_cast,您是在告诉它的类型。如果您改为告诉它一些完全不相关的类型,它甚至可能似乎工作。它只是下面的字节,以不同的方式解释。 (不过应该是Undefined Behaviour)。 -
只有当
v指向C时,强制转换才有效,而它恰好是这样做的。b、v和c恰好都指向同一个地址。当您使用多重继承时,情况并非总是如此,并且强制转换会产生无效的指针。 -
@BoBTFish 但我已经说明它是“C*”,而不是“B*”。
-
您创建了一个
new C,因此在指针的另一端是C对象的有效字节表示。为什么你会惊讶于说“在这个指针的末尾是一个C”(即`static_cast)你得到了预期的值?
标签: c++ c++14 void-pointers static-cast