我使用Qt,我希望我自己的转换系统可能在某些情况下避免dynamic_cast
和qobject_cast
,因为它们很慢(我已经做了一些基准测试,我的解决方案更快,并且< strong> O(1),qobject_cast
和dynamic_cast
O(N))。
在我有基类(在这种情况下为NApplicationElement
)并且每个其他类继承自基类而另一个类充当接口的情况下,我需要快速检查对象是否是特定接口的实例。
因此,我为模型中存在的每个接口选择了基类具有方法virtual Interface* to(Interface* inf) { return static_cast<Interface*>(nullptr); }
的模式,并且如果基类的任何子类实现该接口,它将覆盖基类的适当方法。我使用宏来简化。
H_DEF_INTERFACE
和CPP_DEF_INTERFACE
在基类中用于声明和定义那些默认的to
方法。子类和接口使用H_USE_INTERFACE
和CPP_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
答案 0 :(得分:0)
所以我找到了解决方案。在构造函数初始化列表中,使用指向基类实例的指针初始化接口,对基类的to(NApplicationElement*)
方法的调用需要使用基类名称进行限定。不确定为什么它没有其他工作。有错误的行需要如下:
#define CPP_INTERFACE(inf)inf(NApplicationElement::to(static_cast<NApplicationElement*>(nullptr)))