1

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需要的地方。

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

我在 Windows XP 上使用 Visual Studion 2008。

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

4

1 回答 1

2

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

这就是你的问题:你不能dynamic_castashared_ptr<A>到 ashared_ptr<B>因为这两种类型实际上并不相关,即使AB是。

幸运的是,在您问题的特定情况下,这dynamic_cast不是必需的,因为Record_ID_As_Field*应该可以隐式转换为 a Field_Interface*(因为一个是从另一个派生的)。shared_ptr实现将这些隐式转换提升到相应shared_ptr对象的转换运算符,因此shared_ptr<Record_ID_As_Field>应该可以隐式转换为shared_ptr<Field_Interface>.

如果您省略dynamic_cast,它应该可以工作。

如果您确实需要进行动态转换,则可以使用由以下提供的特殊构造函数shared_ptr

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

(I'm not sure what would happen there if the dynamic_cast fails, so you should investigate what's the best way to handle that situation.)

于 2010-08-20T18:35:40.963 回答