C++ c++;铸造衍生到void*并恢复基础

C++ c++;铸造衍生到void*并恢复基础,c++,casting,C++,Casting,我有: 然后我将C实例存储为void*: class A {...}; class B : public A {...}; class C : public B {...}; 可以这样做吗: C *instance = new C(); void *pC = instance; B*pB=重新解释铸件(pC); 或者我只能投C*吗 PS:在我的程序中,我有更多从B派生的类,我不确定是否可以像我现在这样(对B*)进行转换 为什么无效*:我正在使用box2d引擎中物理实体类的void*us

我有:

然后我将C实例存储为void*:

class A {...};

class B : public A {...};

class C : public B {...};
可以这样做吗:

C *instance = new C();
void *pC = instance;
B*pB=重新解释铸件(pC);
或者我只能投C*吗

PS:在我的程序中,我有更多从B派生的类,我不确定是否可以像我现在这样(对B*)进行转换


为什么无效*:我正在使用box2d引擎中物理实体类的
void*userdata'字段。我不能用其他方式存储我的类,

我建议把它重新转换到原来的代码> C*<代码>,然后按照C++的规则做一个<代码> DyrimixCase<代码> B*<代码>,尽管你应该避免首先使用<代码> Value*/Cuff>,而使用一个基本指针(<代码> A*<代码>)而不是空PTR。

< P>我建议将其返回到原来的<代码> C*<代码>,然后执行<代码> DyrimixCase< /C> > <代码> B*<代码>,以遵循C++的规则——尽管您应该避免首先将其转换为<代码> Value*/Cuff>,而使用基本指针(<代码> A*<代码>)而不是无效ptr。

这将很好地工作。在这种情况下,您只能访问
A
B
方法。(您只需“隐藏”C的方法即可)

这样就可以了。在这种情况下,您只能访问
A
B
方法。(您只需“隐藏”C的方法)

强制转换为void*总是一个坏主意,动态转换也是一个坏主意。如果必须这样做,这主要意味着您的代码需要重新分解,因为这是一个对象设计缺陷。

强制转换为void*总是一个坏主意,动态转换也是如此。如果必须这样做,这主要意味着您的代码需要重新分解,因为这是一个对象设计缺陷。

对于您显示的代码,可以直接转换到
B*
,您可以使用
static\u cast
。但是,一般来说,指向基类和派生类的指针可能不同,您必须先转换为原始类型,然后再转换为指向基类的指针


Edit:在实践中,对于单个继承来说,这应该是可以的,但通常是UB。

对于您显示的代码,直接强制转换到
B*
应该是可以的,您可以使用
static\u cast
。但是,一般来说,指向基类和派生类的指针可能不同,您必须先转换为原始类型,然后再转换为指向基类的指针


Edit:在实践中,对于单个继承来说,这应该是可以的,但通常是UB。

一般规则是,当您从指向
void*
的指针强制转换时,您应该始终强制转换回您最初来自的指针

由于旧的API,有时向空*施放是一种必要的邪恶

有时它是通过设计来创建一个“光”模板的。在light模板中,您可以编写处理指向对象的指针集合的代码,这些指针都以相同的方式处理,这可以防止为每种类型生成代码


围绕这段代码,您有一个强类型模板,它可以执行简单的来回转换(可能是内联的)因此,用户得到的是强类型代码,但实现没有那么臃肿。

一般规则是,当您从指向
void*
的指针进行强制转换时,您应该始终将其强制转换回原来的指针

由于旧的API,有时向空*施放是一种必要的邪恶

有时它是通过设计来创建一个“光”模板的。在light模板中,您可以编写处理指向对象的指针集合的代码,这些指针都以相同的方式处理,这可以防止为每种类型生成代码


围绕这段代码,您有一个强类型模板,它可以进行简单的来回转换(无论如何都可能是内联的),这样用户就可以得到强类型代码,但实现就不那么臃肿了。

我无法避免转换为void*因为为了公平起见,我将我的类存储为另一个外部类的void*userdata字段,
void*
指针结合函数指针和函数模板,是一种很好的类型擦除帮助。不过,您可能不会在用户代码中这样做,而是在库中这样做
dynamic_cast
用于在继承树中向下强制转换。首先需要强制转换到
C*
,否则代码可能会因多重继承而中断。@Andrew我也这么怀疑,无论如何要尽量避免。一旦去掉类型信息(C++中仅有的一点),如果不小心的话,就会出现各种运行时问题。@Xeo是的,如果可能的话,最好像goto一样避免。:-)我无法避免强制转换为void*,因为我将我的类存储为另一个外部类的void*userdata字段。公平地说,
void*
指针结合函数指针和函数模板是一个很好的类型擦除帮助。不过,您可能不会在用户代码中这样做,而是在库中这样做
dynamic_cast
用于在继承树中向下强制转换。首先需要强制转换到
C*
,否则代码可能会因多重继承而中断。@Andrew我也这么怀疑,无论如何要尽量避免。一旦去掉类型信息(C++中仅有的一点),如果不小心的话,就会出现各种运行时问题。@Xeo是的,如果可能的话,最好像goto一样避免。:-)<代码>我不能以其他方式将我的类存储在那里。
-你确定吗?通常,在C++中,将一个纯类转换为模板允许使用诸如<代码> t*UsDATABAS/<代码>代替“代码> VATU*USEDATABAS/CODE >(其中代码“> < /代码>”是模板被实例化的类型。@ FrerichRaabe:I
B *pB = reinterpret_cast<B*>(pC);