无效*保留继承信息
Does void* reserve inheritance information?
void*
可以保持类型信息吗?
我试图使它忘记B* b
到void* 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*
的地址(一个错误的地址(,但似乎知道v
是B*
并正确施放。
问题
为什么起作用?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*
一无所获;所有这些"智能"都在于B
和C
的定义。
- 正在查找文档以获得PS4平台的C++中的设备信息
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 头文件-继承c++
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 为什么在保护模式下继承升级不起作用
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 混合组合和继承的C++问题
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- 公共与私人继承
- C++获取所有继承类信息的方法
- 无效*保留继承信息
- 对"vtable for "命名空间继承的未定义引用 对"类型信息"的未定义引用
- 如何获取继承类C++的信息
- 从继承的对象检索信息
- 如何从通过模板继承的类中提取 typedef'd 信息?
- 编译器对此指针、虚函数和多重继承的详细信息