c++将基指针强制转换为接口指针

C++ casting a base pointer to an interface pointer

本文关键字:指针 转换 接口 c++      更新时间:2023-10-16

下面是我设置的一些伪代码:

class IMyClass { ... }; // pure virtual class
class CMyBaseClass { .... };
class CMyClass : public CMyBaseClass, public IMyClass { ... }

然后我有CMyBaseClass*的集合。我有自定义的RTTI,它允许我发现一个类是否实现了给定的接口。这样我就能找到哪些对象有IMyClass实现。我的问题是我不能将它强制转换到那个接口。我不想使用标准的RTTI和动态强制转换。

我正在考虑在我的自定义RTTI中存储一些指针差异,以便在对类之间进行转换,但我还没有弄清楚使我高兴的实现。

还有其他解决方案吗?

嗯,如果你坚持不使用RTTI语言,你可以像以前的COM那样使用:让你所有的类或接口都从下面的接口派生:

class IMyCast  // similar to IUnknown
{
public:
    virtual void *CastTo(interfaceId_t id) = 0; //Similar to IUnknown::QueryInterface
};

现在在CMyClass中:

class CMyClass : public CMyBaseClass, public IMyClass
{
    //...
    void *CastTo(interfaceId_t id)
    {
        switch (id)
        {
            case IMyClass_id: //or whatever
                return static_cast<IMyClass*>(this);
            //...other cases
            default:
                throw std::bad_cast(); //or return NULL
        }
    }
};

然后在用户代码中:

CMyBaseClass *obj;
IMyClass *my = static_cast<IMyClass*>(obj->CastTo(IMyClass_id));

您可能需要增加您的自定义RTTI;至少这是我在几乎相同的情况下所做的。我的解决方案没有使用指针差异,而是为必要的(Class, Interface)对实例化了一个"caster"函数模板。就像这样:

  • 所有接口都有一个唯一的int id。为此,MyInterface需要从InterfaceBase派生。id是在第一次MyInterface::GetId()调用时自动分配的。
  • MyClass(实现MyInterface)的实现者需要在.cpp文件中添加一个implements (MyClass, MyInterface)宏。
  • 宏实例化一个void* GetInterface<C, I>(void*)函数,然后在interfaceId -> GetInterface-function映射(属于C类)中注册一个指向该函数的指针。该函数将其参数转换为C*,然后将C*转换为I*,最后返回void*。(使用void*的黑客攻击是必要的,以便所有这些函数具有相同的签名,因此它们可以存储在映射中。)
  • 要获得一个接口,用户需要调用myObject->GetInterface()函数,在CMyBaseClass中实现。找到属于this对象的动态类的映射,根据I::GetId()查找相应的caster函数,并通过this调用它。