我有一个从Y和Z(界面)派生的X类。这个类的一个对象作为void *传递给一个库,它只能访问接口Z. [它没有作为Z *传递的原因是有一个只接受void *的中间组件]
带有gcc thunk的vtable的布局是X,Y指向相同的地址,但Z指向X + 8
所以,我需要将对象强制转换为(Z *)(obj + 8)才能到达Z.这是否安全,有替代方案吗?我不能使用RTTI。
答案 0 :(得分:3)
在这种情况下,只需使用static_cast
显式转换为要发送的类型。它会处理细节,只要它知道它的类型是转换的。
那是:
X *theX = ...;
void *ptr = static_cast<Z*>(theX)
然后在接收代码中:
void *ptr = ...;
Z *theZ = static_cast<Z*>(ptr);
如果您知道它实际上是X
:
X *theX = static_cast<X*>(theZ);
底线是:无论何时将指针转换为void*
并返回,它都应转换为与之前相同的类型。
因此,这是未定义的:
X *theX = ...;
void *ptr = static_cast<void*>(theX);
Z *theZ = static_cast<Z*>(ptr); //Undefined behavior!!!
事件虽然Z
是X
的子类,但两者之间的直接static_cast
会有效。
答案 1 :(得分:2)
不,施放(Z*)(obj + 8)
并不安全。
在投射到Z*
之前将对象投射到void*
,然后将void*
投回Z*
。那将是安全的。