C++ 如何正确检查对象是否实现了接口

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

我想为某些对象实现自定义行为

为此,让我的项目(从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();  
如果(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 ) ) ...