在C++多重继承的情况下如何获得正确的指针"alignment"?

How to get the right pointer "alignment" in case of multiple inheritance in C++?

本文关键字:指针 alignment 何获得 C++ 多重继承 情况下      更新时间:2023-10-16

假设我有两个接口IFooIBar;加上实现这些接口的具体类型FooBar:

class FooBar : public IFoo, public IBar
{
    //FooBar stuff
};

某处我得到一个void*指针,指向FooBar实例。

void* fooBar = getOrCreateStuff();

现在我想从我的fooBar实例中获得IBar的指针。

IBar* iBar = static_cast< IBar* >(fooBar);

不幸的是,iBar没有指向正确的内存地址。这个例子故意很傻——在现实生活中,我不知道我所指的具体类型。

EDIT:我正在编写一个API,在那里我暴露template <class StuffT> StuffT getOrCreateStuff()方法。在这一点上,绝对没有办法知道开发者使用的是什么类型。上面的例子向你们展示了这种方法应该如何使用。我们在API中注册一个具体类型,并将其作为接口获取。在处理单继承时,它很有魅力,但多继承更复杂。

有没有办法让我的iBar指向工作地址偏移?

如果你不知道你指的是什么,那你就倒霉了!使用static_cast(v),其中"v"的类型为"void*",只有当"v"是由隐式转换为"void*"产生时,才能强制转换为"T*"类型。如果你真的得到一个"void*",你需要首先恢复一个类型"B*"(例如某种基类;它不必是所有分支的公共基类,只是已知存在),至少有一个虚函数(例如,如果没有任何功能,它的析构函数),从那里你可以使用dynamic_cast(b)来恢复继承层次结构中的某些类型。请注意,如果实际对象中有多个"T"子对象,即使这样也不一定有效。

所有这些都是必要的原因是,在使用多重继承的对象中,指向子对象的指针正在被调整:根据您在哪个分支中,可能存在相同的子对象,而处理特定的子对象需要不同的指针。您可以避免使用dynamic_cast(b),但前提是您可以有效地创建自己的运行时信息系统。

getOrCreateStuff()更改为返回void*以外的内容。如果它返回IStuff*,并且FooBar派生自IStuff,那么您可以使用dynamic_cast来获得IBar*

如果你确定:"某处我得到一个void*指针,指向FooBar实例。"

那么,这是一个解决方案:

IBar* iBar = static_cast<IBar*>(reinterpret_cast< FooBar* >(fooBar));

或:

IBar* iBar = dynamic_cast<IBar*>(reinterpret_cast< FooBar* >(fooBar));

由于IBar是一个接口,它必须有一个纯虚方法,所以它是多态的,所以可以使用动态强制转换