将 class 转换为 class
Casting a class to a class
[这里是嵌入式C的人,被嵌入式C++搞糊涂了]
有一个class派生自另一个,如下:
class DerivedThing: public BaseThing {
...
}
有一些我无法控制的代码,它接收指向 DerivedThing
的指针,最终 casts 指向 [=16= 的指针].我被引导相信这是有效的。不管怎样,我需要实现我自己的 DerivedThing
但它需要 subclass 一些其他的东西:
class MyDerivedThing: public BaseThing, public AnotherThing {
...
}
我需要做什么才能确保演员阵容仍然有效?我问是因为在我的情况下,肯定会调用错误的函数。
编辑:我无法控制的代码中的转换是:
int setInterface(void* context)
{
interface[0] = (BaseThing *) context;
...
我评论的时候太悲观了!
自己转换为 BaseThing*
,然后将 that 传递给采用 void*
的函数应该可以工作。
按原样传递派生对象地址的问题是它的地址被隐式转换为 void*
。因此,有关其类型和涉及的 class 层次结构的所有信息都将丢失。
然后接收函数假定 now-void*
指针直接指向 BaseThing
。这是事情开始变得循环的地方,表现为调用错误函数的症状 - 如果你幸运的话 - 因为假设派生对象和任何特定的基本子对象具有相同的地址不是 (always/reliably) 多个 and/or 虚拟继承在起作用的有效假设。
中场休息:目前尚不清楚为什么这种引用的碱基顺序会导致问题:
class MyDerivedThing: public BaseThing, public AnotherThing {
...但是有多种可能性。比如这里的三个class都没有虚方法,那应该没有问题。但是,例如,如果 BaseThing
不是虚拟的,而其他两个中的任何一个是,编译器可能会在对象的顶部放置一个虚拟的 table 指针,这将炸毁任何只接受它的东西地址并假设那里有一个 BaseThing
。
无论如何 - 通过在传递之前转换你自己,编译器可以进行适当的类型感知转换,执行任何可能需要的调整算法,到你的对象中 BaseThing
的地址 - 然后传递它到功能。它仍然会经历到 void*
的转换并返回,但现在可以保证最终代表 BaseThing
的地址。
我仍然会质疑作者为什么这个函数需要 void*
。 C++ 的关键之一是类型安全。 void*
对此进行了嘲讽。更糟糕的是,他们只是立即将 said void*
转换为 BaseThing*
。那么,为什么不直接...首先使用 BaseThing*
呢?然后编译器可以在任何调用站点隐式执行提到的安全类型转换,而不是让你这样做。
[这里是嵌入式C的人,被嵌入式C++搞糊涂了]
有一个class派生自另一个,如下:
class DerivedThing: public BaseThing {
...
}
有一些我无法控制的代码,它接收指向 DerivedThing
的指针,最终 casts 指向 [=16= 的指针].我被引导相信这是有效的。不管怎样,我需要实现我自己的 DerivedThing
但它需要 subclass 一些其他的东西:
class MyDerivedThing: public BaseThing, public AnotherThing {
...
}
我需要做什么才能确保演员阵容仍然有效?我问是因为在我的情况下,肯定会调用错误的函数。
编辑:我无法控制的代码中的转换是:
int setInterface(void* context)
{
interface[0] = (BaseThing *) context;
...
我评论的时候太悲观了!
自己转换为 BaseThing*
,然后将 that 传递给采用 void*
的函数应该可以工作。
按原样传递派生对象地址的问题是它的地址被隐式转换为 void*
。因此,有关其类型和涉及的 class 层次结构的所有信息都将丢失。
然后接收函数假定 now-void*
指针直接指向 BaseThing
。这是事情开始变得循环的地方,表现为调用错误函数的症状 - 如果你幸运的话 - 因为假设派生对象和任何特定的基本子对象具有相同的地址不是 (always/reliably) 多个 and/or 虚拟继承在起作用的有效假设。
中场休息:目前尚不清楚为什么这种引用的碱基顺序会导致问题:
class MyDerivedThing: public BaseThing, public AnotherThing {
...但是有多种可能性。比如这里的三个class都没有虚方法,那应该没有问题。但是,例如,如果 BaseThing
不是虚拟的,而其他两个中的任何一个是,编译器可能会在对象的顶部放置一个虚拟的 table 指针,这将炸毁任何只接受它的东西地址并假设那里有一个 BaseThing
。
无论如何 - 通过在传递之前转换你自己,编译器可以进行适当的类型感知转换,执行任何可能需要的调整算法,到你的对象中 BaseThing
的地址 - 然后传递它到功能。它仍然会经历到 void*
的转换并返回,但现在可以保证最终代表 BaseThing
的地址。
我仍然会质疑作者为什么这个函数需要 void*
。 C++ 的关键之一是类型安全。 void*
对此进行了嘲讽。更糟糕的是,他们只是立即将 said void*
转换为 BaseThing*
。那么,为什么不直接...首先使用 BaseThing*
呢?然后编译器可以在任何调用站点隐式执行提到的安全类型转换,而不是让你这样做。