如何正确检查对象是否实现了接口
How to correctly check if an object implements an interface
我想为某些对象实现自定义行为。
为此,让我的项目(从QGraphicsItem继承)实现一些接口。
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();
不幸的是这个崩溃了…通常…所以我创建了一个旗子来测试,如果旗子是真的,只有那时才敢投射。
但我一直在想,它不应该崩溃。所以我鼓起勇气再次尝试,这次是在一个QWidget子程序中。不是crash而是
QWidget::insertAction: Attempt to insert null action
是测试if(item1 == NULL)
给出了这个消息…
如何正确检查我的项目是否实现了SomeInterface
?
备注:item
不能为空。
可能有一个编译器开关禁用运行时类型信息,在这种情况下,它将解释行为。否则item1只能是非空的,如果dynamic_cast有效
一个简单的泛型模板可以使代码更容易读,更容易实现。
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
。如果您尝试这样做:
if ( isSomeInterface(instance) ) instance.function2();
上没有实现function2的类,编译器将执行因为它不能绑定到该实例的function2,也就是说正确,但不直观,因为它看起来不会从左到右逻辑调用。然而,编译器无法在编译时知道isSomeInterface
将返回什么。
这种技术被许多人认为不是一种"好风格"的编程,因为它可能导致c++面条和代码膨胀,并且变得难以维护和调试。dynamic_cast
通常用于区分类层次结构中的同名函数,特别是基类和子类方法,以及在方法签名重叠的多重继承情况下,确定地为情况选择正确的方法。
// safe implements
#define implements( C, I ) ( __extension__ ({
static bool impl=(dynamic_cast<I*>(&C))? true : false;
impl;
}))
if ( implements( instance, SomeInterface ) ) ...
如果需要,是一个宏,用于在运行时检查接口遵从性。但是,要节约使用。如果你在一段时间内不止一次这样做,你的代码很可能需要重构。
这样简单:
class SomeInterface
{
virtual void function2() = 0;
virtual qint32 role() =0;
};
和返回一个不同的int自定义行为?
相关文章:
- 如何从实现接口的模板化类实例访问结构
- 如何在C++中实现接口
- unique_ptr实现接口时对已删除函数的引用
- 避免对实现接口的类使用多个几乎相同的声明
- C#COM组装实现C 接口
- 当传递对类的引用时,优于另一个函数,即实现接口
- 通过其方法的子集实现接口
- C ++类实现接口,接口具有采用任何实现该接口的类的方法
- 错误:在 C++ 中实现接口模式时未定义对 typeinfo 的引用
- 与模板实现接口的类模板
- 在主应用程序中声明的 dll 中实现接口 - C++
- Objective-C类实现C 接口
- 如何添加实现C 接口的标签
- 强制接收实现接口的超类指针作为方法的参数
- 我可以部分实现接口层次结构吗
- 是否可以通过继承实现接口
- 在c++中实现接口
- 如何使用谷歌测试测试实现接口的不同类/结构
- 使用成员函数模板实现接口的功能
- C++ 11 实现接口的方法不可用。为什么?