动态转换和多重继承

时间:2010-08-20 18:15:01

标签: c++ pointers multiple-inheritance dynamic-cast

当我应用于指向多重继承对象实例的指针时,dynamic_cast运算符返回零(0)。我不明白为什么。

层次结构:

class Field_Interface
{
  public:
    virtual const std::string get_field_name(void) const = 0; // Just to make the class abstract.
};


class Record_ID_Interface
{
  public:
    virtual bool has_valid_id(void) const = 0;
};


class Record_ID_As_Field
: public Field_Interface,
  public Record_ID_Interface
{
// This class behaves as a Field and a Record_ID.
// ...
}


// A demonstration function
void Print_Field_Name(const Field_Interface * p_field)
{
  if (p_field)
  {
    cout << p_field->get_field_name() << endl;
  }
  return;
}


// A main function for demonstration
int main(void)
{
  Record_ID_As_Field *  p_record_id = 0;
  p_record_id = new Record_ID_As_Field;
  if (p_record_id)
  {
     // (1) This is the trouble line
     Print_Field_Name(dynamic_cast<Field_Interface *>(p_record_id));
  }
  return 0;
}

我希望Record_ID_As_Field被视为Field_Interface,但也适合需要Record_ID_Interface的地方。

为什么上面(1)中的dynamic_cast返回0,我该如何解决?

我在Windows XP上使用Visual Studion 2008。

注意:为简单起见,我在本例中使用基本指针。实际代码使用boost::shared_ptr

1 个答案:

答案 0 :(得分:2)

  

注意:为简单起见,我在本例中使用基本指针。实际代码使用boost::shared_ptr

那就是你的问题:你不能dynamic_cast shared_ptr<A>shared_ptr<B>,因为这两种类型实际上并不相互关联,即使AB是。{/ p>

幸运的是,在您的问题的具体情况下,dynamic_cast不应该是必要的,因为Record_ID_As_Field*应该隐式转换为Field_Interface*(因为一个来自另一个) 。 shared_ptr实现了将这些隐式转化提升到相应shared_ptr个对象的转化运算符,因此shared_ptr<Record_ID_As_Field>应隐式转换为shared_ptr<Field_Interface>

如果遗漏dynamic_cast,它应该有效。

如果您确实需要进行动态广告投放,可以使用shared_ptr提供的special constructor

shared_ptr<Record_ID_As_Field> raf;
shared_ptr<Field_Interface> fi(raf, dynamic_cast<FieldInterface*>(raf.get());

(我不确定如果dynamic_cast失败会发生什么,所以你应该调查处理这种情况的最佳方法。)