C++ 如何正确检查对象是否实现了接口
我想为某些对象实现自定义行为 为此,让我的项目(从QGraphicsItem继承)实现一些接口C++ 如何正确检查对象是否实现了接口,c++,qt,inheritance,multiple-inheritance,C++,Qt,Inheritance,Multiple Inheritance,我想为某些对象实现自定义行为 为此,让我的项目(从QGraphicsItem继承)实现一些接口 class SomeParentItem { SomeParentItem(bool x) { x = true; } void function1() {} }; class SomeInterface { virtual void function2() = 0; }; class XYZItem : public QGraphicsXYZItem, public S
class SomeParentItem
{
SomeParentItem(bool x) { x = true; }
void function1() {}
};
class SomeInterface
{
virtual void function2() = 0;
};
class XYZItem : public QGraphicsXYZItem, public SomeParentItem, public SomeInterface
{
XYZItem(bool x):SomeParentItem(x) {}
virtual void function2() { x = false; }
};
class MPQItem : public QGraphicsMPQItem, public SomeParentItem
{
MPQItem (bool x):SomeParentItem(x) {}
};
从外面看,我在想我就是这么做的
SomeInterface* item1 = dynamic_cast<SomeInterface*>(item);
if(item1 == NULL)
item->function1();
else
item1->function2();
如果(item1==NULL)给出该消息,则是测试
如何正确检查我的项目是否实现了SomeInterface
注意:项
不能为空 像这样简单的事情怎么样:
class SomeInterface
{
virtual void function2() = 0;
virtual qint32 role() =0;
};
为自定义行为返回不同的int?可能有一个编译器开关,它禁用运行时类型信息,在这种情况下,它将解释行为。否则,item1应仅为非null,如果动态转换有效,则简单的泛型模板可以使代码更可读且更易于实现
template < class T >
bool is_SomeParentItem( T& P)
{
if ( dynamic_cast<SomeParentItem*>(&P) )
return true;
else
return false;
}
template < class T >
bool is_SomeInterface( T& I)
{
if ( dynamic_cast<SomeInterface*>(&I) )
return true;
else
return false;
}
template < class T >
void function( T& X)
{
if ( isSomeInterface(X) )
{
dynamic_cast<SomeInterface*>(&X)->function2();
return;
}
if ( isSomeParentItem(X) )
dynamic_cast<SomeParentItem*>(&X)->function1();
}
在未实现function2的类上,编译器将
阻止,因为它无法绑定到该实例的function2,即
正确但不直观,因为它看起来不会从左向右逻辑调用。但是,编译器无法在编译时知道isSomeInterface
将返回什么
<> P>这种技术并不是许多人认为是一种“好的编程风格”,因为它会导致C++的意大利面和代码臃肿,并且变得难以维护和调试。
dynamic\u cast
通常用于区分类层次结构中相同的命名函数,特别是基类与子类方法,并且在方法签名重叠的多重继承情况下,用于根据情况确定选择正确的方法
// safe implements
#define implements( C, I ) ( __extension__ ({ \
static bool impl=(dynamic_cast<I*>(&C))? true : false; \
impl; \
}))
if ( implements( instance, SomeInterface ) ) ...
//安全工具
#定义实现(C,I)(扩展名)
静态bool impl=(动态_cast(&C))?true:false;\
impl;\
}))
如果(实现(实例,SomeInterface))。。。
是一个宏,用于在运行时检查接口符合性(如果需要)。
但是,请谨慎使用。
如果您在很长一段时间内不止一次这样做,您的代码很可能需要重构。请注意,如果item
为null,那么您将调用function2()
对item1
进行调用,而item
也将为null。item
不能为null您会遇到什么样的崩溃?您是否尝试测试项是否为空?这似乎是它崩溃的唯一途径dynamic_cast
是为实现的接口测试对象的正常方法。在小部件本身上修复了一些东西之后,我再也不会收到错误了。。我无法解释为什么之前取消测试也不会出现错误。。。感谢您查看我的问题,但我似乎是在根据症状排除错误的问题。这并没有回答问题,并且引入了对要引导的幻数的依赖。
if ( isSomeInterface(instance) ) instance.function2();
// safe implements
#define implements( C, I ) ( __extension__ ({ \
static bool impl=(dynamic_cast<I*>(&C))? true : false; \
impl; \
}))
if ( implements( instance, SomeInterface ) ) ...