C ++将一个基指针转换为接口指针

时间:2011-08-04 07:35:33

标签: c++ casting rtti

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

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

然后我收集了CMyBaseClass *。我有自定义RTTI,它允许我找出一个类是否实现给定的接口。所以我可以找到哪些对象有IMyClass实现。我的问题是我无法将其强制转换为该界面。我不想使用标准的RTTI和动态演员。

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

还有其他解决方案吗?

2 个答案:

答案 0 :(得分:5)

好吧,如果你坚持不使用语言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));

答案 1 :(得分:1)

您可能需要增加自定义RTTI;至少这是我在几乎相同的情况下所做的。我的解决方案不是使用指针差异,而是为必要的(类,接口)对实例化一个“脚轮”功能模板。它是这样的:

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