Динамическое приведение и множественное наследование - PullRequest
1 голос
/ 20 августа 2010

Оператор 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 и как мне решить эту проблему?

Я использую Visual Studion 2008 в Windows XP.

Примечание. Для простоты в этом примере я использую основные указатели.Фактический код использует boost::shared_ptr.

1 Ответ

2 голосов
/ 20 августа 2010

Примечание. Для простоты в этом примере я использую основные указатели.Фактический код использует boost::shared_ptr.

И в этом ваша проблема: вы не можете dynamic_cast a shared_ptr<A> до shared_ptr<B>, поскольку эти два типа на самом деле не связаны друг с другом, дажеесли A и B.

К счастью, в конкретном случае в вашем вопросе 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:

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

(я не уверен, что произойдет, если произойдет сбой dynamic_cast, поэтому вам следует выяснить, как лучше всего справиться с этой ситуацией.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...