Оператор 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
.
Примечание. Для простоты в этом примере я использую основные указатели. Фактический код использует
boost :: shared_ptr
.
Вот и ваша проблема: вы не можете dynamic_cast
a shared_ptr
на shared_ptr
, поскольку эти два типа на самом деле не связаны друг к другу, даже если A
и B
равны.
К счастью, в конкретном случае в вашем вопросе dynamic_cast
не требуется, поскольку Record_ID_As_Field *
должен быть неявно преобразован в Field_Interface *
(поскольку одно происходит от другого). shared_ptr
реализует операторы преобразования, которые поднимают эти неявные преобразования в соответствующие объекты shared_ptr
, поэтому shared_ptr
должен быть неявно преобразован в shared_ptrface
.
Если вы не укажете dynamic_cast
, он должен работать.
Если вам действительно нужно выполнить динамическое приведение, вы можете использовать специальный конструктор , предоставленный shared_ptr
:
shared_ptr<Record_ID_As_Field> raf;
shared_ptr<Field_Interface> fi(raf, dynamic_cast<FieldInterface*>(raf.get());
(я не уверен, что там произойдет если dynamic_cast
дает сбой, вам следует выяснить, как лучше всего справиться с этой ситуацией.)