2012-08-28 15 views
14

devo classe base A, classe B eredita da A, classe C che è una classe template eredita dalla classe A. D eredita da C. La relazione è il seguente:circa dynamic_cast C++ con classe template

 A 
    /\ 
     B C (template class) 
      \ 
      D 

Posso creare un oggetto A O1 utilizzando l'oggetto D D1, quindi voglio il cast dinamico O1 a un oggetto di tipo C C1. Ma trovo che fallisce. La mia domanda è perché questo processo fallisce?

Quindi uso static_cast per creare l'oggetto di tipo C C2 dall'oggetto D D1 e ho verificato che C2 ha il valore corretto da D2. È sempre utile convertire dal tipo D al tipo C usando static_cast?

Grazie !!!

+1

Inserire il codice completo, insieme ai risultati previsti ed effettivi. Ci sono un numero infinito di cose che potrebbero andare storte e non possiamo dire quale sia senza un codice specifico. – Mankarse

+0

La tua classe base ha funzioni virtuali? In caso contrario, non è possibile utilizzare 'dynamic_cast'. – GManNickG

+0

Ricorda che la maggior parte di queste conversioni è valida solo per puntatori e riferimenti, non per gli oggetti stessi. Non è chiaro dalla tua descrizione esattamente quello che stai cercando di convertire; qualche codice di esempio sarebbe utile. –

risposta

13

Bene, poiché C è un modello, non è un tipo e non può essere utilizzato come destinazione di un cast (né dinamico per statico) e non è possibile derivarne. È necessario istanziare il modello di classe. La classe risultante può essere essere utilizzata in un cast. Cioè, il seguente funzionerà:

struct A { }; 
template <typename T> struct C : A { }; 
struct D : C<int> { }; 

D d; 
A& a = d; 
C<int>& c = static_cast<C<int>&>(a); // or dynamic_cast, if `A` were polymorphic 
+1

dynamic_cast sarebbe un comportamento non definito qui, mentre esegui il down-cast con un tipo non polimorfico (devi aggiungere almeno una funzione virtuale per far funzionare dynamic_cast). – IceCool

+1

@IceCool Corretto, ho aggiunto un chiarimento. –

+0

Se si ha 'errore C2683: 'dynamic_cast': '...' non è un tipo polimorfico' basta aggiungere un * distruttore virtuale * alla classe base:' virtuale ~ A() {} ' – 56ka

9

ad un C1 tipo C oggetto. Ma trovo che fallisce.

Poiché C è un modello, non esiste realmente "tipo C". Piuttosto, c'è C<int> o C<Foo>. (supponendo che tu abbia un template arg). I modelli diventano solo classi quando sono specializzati.

Quindi, se D ereditato da un tipo specifico di C:

class D : public C<int> 
{ 
}; 

si poteva dynamic_cast fino ad un C<int> ma non dire una C<float>

Per aiutare spiegare meglio, il vostro albero di ereditarietà è davvero

  A 
    /| \ 
C<float>... C<int> 
      | 
      D 

Quindi C non è un genitore di D, ma C<int> è in questo esempio. Le istanze di C non sono realmente presenti nel runtime, le sue uniche istanze completamente specificate di C<type> effettivamente esistenti.

+1

Non solo runtime -' C' non è un tipo, punto. –

Problemi correlati