Domanda

L'operatore dynamic_cast restituisce zero (0) quando applico ad un puntatore che punti a un'istanza di un oggetto moltiplicano ereditato. Non capisco perché.

La gerarchia:

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;
}

Io voglio avere la Record_ID_As_Field di essere trattato come un Field_Interface, ma inserirsi anche in cui sono richiesti Record_ID_Interface.

Perché è dynamic_cast in (1) sopra ritorno 0, e come si risolve questo?

Sto usando Visual Studion 2008 su Windows XP.

Nota: Per semplicità, sto usando puntatori fondamentali in questo esempio. Actual utilizza codice boost::shared_ptr.

È stato utile?

Soluzione

  

Nota: Per semplicità, sto usando puntatori fondamentali in questo esempio. codice vero e utilizza boost::shared_ptr.

E questo è il problema proprio lì. Non è possibile dynamic_cast un shared_ptr<A> ad un shared_ptr<B> poiché queste due tipi non sono effettivamente correlati tra loro, anche se A e B sono

Per fortuna, nel caso specifico in questione il dynamic_cast non dovrebbe essere necessario, dal momento che Record_ID_As_Field* dovrebbe essere implicitamente convertibile ad un Field_Interface* (dato che quello è derivato da l'altro). attrezzi shared_ptr operatori di conversione che sollevano queste conversioni implicite ai rispettivi oggetti shared_ptr, così shared_ptr<Record_ID_As_Field> deve essere convertita in modo implicito shared_ptr<Field_Interface>.

Se si lascia la dynamic_cast, dovrebbe funzionare.

Se desideri in realtà bisogno di fare un cast dinamico, è possibile utilizzare un speciale costruttore fornita da shared_ptr:

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

(io non sono sicuro di cosa sarebbe successo lì se la dynamic_cast non riesce, quindi si dovrebbe indagare qual è il modo migliore per gestire questa situazione.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top