我想为某些对象实现自定义行为。
为此,让我的项目(继承自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孩子。而不是崩溃我得到了
QWidget::insertAction: Attempt to insert null action
测试if(item1 == NULL)
给出了这个消息......
如果我的项目实现SomeInterface
?
注意:item
不能为空。
答案 0 :(得分:1)
可能有一个编译器开关禁用运行时类型信息,在这种情况下它会解释行为。否则,如果dynamic_cast工作
,则item1应该只是非null答案 1 :(得分:0)
简单的通用模板可以使代码更易读,更容易实现。
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 ) ) ...
是一个宏,用于在运行时检查接口合规性(如果需要)。 但是,请谨慎使用。 如果你在很长一段时间内不止一次这样做,你的代码很可能需要重构。
答案 2 :(得分:-2)
如此简单的事情:
class SomeInterface
{
virtual void function2() = 0;
virtual qint32 role() =0;
};
为自定义行为返回一个不同的int?