自定义强制转换系统,以避免慢速dynamic_cast和qobject_cast

时间:2015-11-30 22:07:16

标签: c++

我使用Qt,我希望我自己的转换系统可能在某些情况下避免dynamic_castqobject_cast,因为它们很慢(我已经做了一些基准测试,我的解决方案更快,并且< strong> O(1),qobject_castdynamic_cast O(N))。

在我有基类(在这种情况下为NApplicationElement)并且每个其他类继承自基类而另一个类充当接口的情况下,我需要快速检查对象是否是特定接口的实例。

因此,我为模型中存在的每个接口选择了基类具有方法virtual Interface* to(Interface* inf) { return static_cast<Interface*>(nullptr); }的模式,并且如果基类的任何子类实现该接口,它将覆盖基类的适当方法。我使用宏来简化。

H_DEF_INTERFACECPP_DEF_INTERFACE在基类中用于声明和定义那些默认的to方法。子类和接口使用H_USE_INTERFACECPP_USE_INTERFACE(它们只是覆盖基类的to方法)。

有这个宏CPP_INTERFACE,导致下面的错误。这个宏在构造函数初始化列表中用于初始化接口,指针指向基类的实例,我需要支持转换FROM接口。没有它,就可以只投射TO接口。您可以看到我正在尝试初始化界面inf 使用基类方法to(NApplicationElement*)返回的值。但是我在下面得到了那个奇怪的错误。有人知道为什么会这样吗? 我强制转换nullptr,因为我希望强制编译器因方法重载而调用正确的方法。

 #define CPP_INTERFACE(inf) inf(to(static_cast<NApplicationElement*>(nullptr)))

错误:来自&#39; NApplicationElement *&#39;的无效转换到&#39; NCustomElement *&#39; [-fpermissive]

#ifndef INTERFACE
#define INTERFACE

// this is just to try how much is the qobject_cast sensitive to class name length
//#define NApplicationElement Aasfasfasfasfasfsasafasfasfa
//#define NWindow Basfasfasfasfasfasfasfsafas
//#define NCustomElement Casfasfasfasfasfasfasfasf

#define N_CAST
//#define Q_CAST
//#define CPP_CAST

template <typename T, typename D>
T ncast(D obj) {
    return obj->to(static_cast<T>(nullptr));
}

#define H_INTERFACE(ifn) public ifn
// this previous version using only macros needs to be reworked using template to support
// cast from interface
//#define CPP_INTERFACE(inf) inf(toNApplicationElement())
//#define H_USE_INTERFACE(inf) virtual inf* to##inf() /* Q_DECL_OVERRIDE */;
//#define CPP_USE_INTERFACE(clazz, inf) inf* clazz::to##inf() { return static_cast<inf*>(this); }
//#define H_DEF_INTERFACE(inf) virtual inf* to##inf();
//#define CPP_DEF_INTERFACE(clazz, inf) inf* clazz::to##inf() { return nullptr; }

#define CPP_INTERFACE(inf) inf(to(static_cast<NApplicationElement*>(nullptr)))
#define H_USE_INTERFACE(inf) virtual inf* to(inf* t) /* Q_DECL_OVERRIDE */;
#define CPP_USE_INTERFACE(clazz, inf) inf* clazz::to(inf* t) { return static_cast<inf*>(this); }
#define H_DEF_INTERFACE(inf) virtual inf* to(inf* t);
#define CPP_DEF_INTERFACE(clazz, inf) inf* clazz::to(inf* t) { return nullptr; }

#if defined(N_CAST)

#define CAST(obj, clazz) ncast<clazz*, decltype(obj)>(obj)
// previous version using only macros (will not work for casting from interface)
//#define CAST(obj, clazz) (obj->to##clazz())

#elif defined(Q_CAST)

#define CAST(obj, inf) (qobject_cast<inf*>(obj))

#else

#define CAST(obj, inf) (dynamic_cast<inf*>(obj))

#endif

#define INTERFACE_CONSTRUCTOR(inf) inf(NApplicationElement* upcast) : NModelInterface(upcast) { }

class NApplicationElement;

// every interface needs to inherit from this so we can than somehow to use the m_upcast for casting
// from interface
class NModelInterface
{
    NApplicationElement* m_upcast;
public:
    NModelInterface(NApplicationElement* upcast) { m_upcast = upcast; }

};

#endif // INTERFACE

1 个答案:

答案 0 :(得分:0)

所以我找到了解决方案。在构造函数初始化列表中,使用指向基类实例的指针初始化接口,对基类的to(NApplicationElement*)方法的调用需要使用基类名称进行限定。不确定为什么它没有其他工作。有错误的行需要如下:

#define CPP_INTERFACE(inf)inf(NApplicationElement::to(static_cast<NApplicationElement*>(nullptr)))