Dynamische Besetzung und Mehrfachvererbung
-
30-09-2019 - |
Frage
Der dynamic_cast
Operator zurückkehrt Null (0), wenn I auf einen Zeiger, der auf eine Instanz eines mehrfach vererbten Objekts anwenden. Ich verstehe nicht, warum.
Die Hierarchie:
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;
}
Ich möchte die Record_ID_As_Field
haben als Field_Interface
behandelt werden, sondern passen auch in dem Record_ID_Interface
erforderlich sind.
Warum ist dynamic_cast
in (1) oben 0 Rückkehr und wie dies ich lösen?
Ich bin mit Visual Studion 2008 unter Windows XP.
Hinweis: Der Einfachheit halber verwende ich grundlegende Hinweise in diesem Beispiel. Die tatsächliche Code Verwendungen boost::shared_ptr
.
Lösung
Hinweis: Der Einfachheit halber verwende ich grundlegende Hinweise in diesem Beispiel. Die tatsächliche Code verwendet
boost::shared_ptr
.
Und das ist Ihr Problem genau dort. Sie können keine dynamic_cast
zu einem shared_ptr<A>
shared_ptr<B>
da diese beiden Typen sind nicht wirklich miteinander verwandt, auch wenn A
und B
sind
Zum Glück im konkreten Fall in Frage sollte die dynamic_cast
nicht nötig sein, da Record_ID_As_Field*
zu einem Field_Interface*
implizit konvertierbar sein sollte (da die eine von den anderen abgeleitet ist). Implementiert shared_ptr
Umwandlungsoperator, die diese impliziten Konvertierungen zu den jeweiligen Objekten shared_ptr
heben, so shared_ptr<Record_ID_As_Field>
zu shared_ptr<Field_Interface>
implizit konvertierbar sein sollte.
Wenn Sie die dynamic_cast
auslassen, sollte es funktionieren.
Wenn Sie tatsächlich benötigen würde eine dynamische Umwandlung zu tun, könnten Sie verwenden, um eine Sonder Konstruktor von shared_ptr
bereitgestellt:
shared_ptr<Record_ID_As_Field> raf;
shared_ptr<Field_Interface> fi(raf, dynamic_cast<FieldInterface*>(raf.get());
(Ich bin nicht sicher, was dort passieren würde, wenn die dynamic_cast
ausfällt, so sollten Sie untersuchen, was ist der beste Weg, um diese Situation zu handhaben.)