2012-02-01 8 views
6

ho un vettore di puntatori a oggetti derivati ​​inserire dall'utente (quindi credo che il termine corretto è "conosciuta solo in fase di esecuzione) ::utilizzo di typeid per fare un confronto tra le classi derivate

vector<Person *> vect; 

Il classi derivate sono maschio e femmina voglio fare un'iterazione sul vettore per selezionare solo gli oggetti femminili e chiamare il copyconstructor di quel ho pensato 3 soluzioni:

  1. di utilizzare una bandiera;
  2. .. Per utilizzare typeid
  3. Per inserire una chiamata al costruttore di copie nel costruttore predefinito di Female, quindi ogni volta che l'utente ne crea uno, crea automaticamente il gemello.

Non mi piace la prima opzione nel caso di molti tipi di classi derivate. Anche la terza opzione non mi piace perché causerebbe un problema di relazione (il Mondo conosce ogni femmina ma la femmina non può conoscere il mondo). quindi dovrei usare la seconda opzione: esempio

typeid(vect.at(i))==typeid(Female) 

È questo espressione corretta? C'è un altro modo per delineare il problema?

+5

E 'difficile dare consigli sulla base di un esempio come questo. In questo caso direi semplicemente di usare una bandiera, perché il sesso è una caratteristica di una persona. L'ereditarietà sembra un modo stupido per modellarlo. –

+1

'typeid (vect.at (i)) == typeid (Female)' non funziona –

+0

Sono d'accordo con @ R.MartinhoFernandes, ma se provi ancora il polimorfismo di un cast dinamico potrebbe essere utile qui. – L7ColWinters

risposta

7

Avere Male e Female ereditano da Person suona come un design davvero strano, ma qui andiamo:

vector<Person*> vect; 
vector<Female*> females; 
for (vector<Person*>::const_iterator it = vect.begin(); it != vect.end(); ++it) 
{ 
    if (Female* p = dynamic_cast<Female*>(*it)) 
    { 
     females.push_back(p); // copy the pointer 
    } 
} 

Se davvero si vuole eseguire una copia del femminile, che suona di nuovo strano, sostituire l'ultimo linea con:

 females.push_back(new Female(*p)); // copy the pointee 
+0

Non mi ricordo di scriverlo ma Person è una classe astratta. Il tuo codice è buono ma devo cambiare la (nuova femmina (* p)) con una chiamata a una funzione clone, suppongo che sia – Ale

+1

Perché? Al punto di 'push_back', già * sai * che hai una' Femmina 'a portata di mano. Oppure 'Female' ha altre sottoclassi? * Solo allora * chiamerebbe una funzione di clone polimorfico avere un senso. – fredoverflow

+0

sì, hai ragione! – Ale

3
typeid(vect.at(i))==typeid(Female) 

è errato se vect contiene puntatori. Vuoi dire

typeid(*vect.at(i)) == typeid(Female)) 

Sia typeid o dovrebbe essere usato una bandiera semplice dipende l'architettura del programma, in particolare se si ha realmente bisogno il polimorfismo. Non capisco davvero la tua terza opzione.

+0

la terza opzione forse non funziona ma consiste nell'inserire una funzione clone nel costruttore di Female per chiamare il costruttore copy copy. Ad ogni modo, preferisco il typeid o il cast dinamico. grazie – Ale

3

Non modellare il genere con ereditarietà, ma piuttosto utilizzare un tipo enumerato in Person. Quindi è possibile utilizzare transform o remove_copy_if o simile per trovare gli oggetti indicati femminili.

1

È anche possibile utilizzare dynamic_cast per eseguire questa operazione. Per esempio, questo rende punto fp ad una femmina nel caso in cui pp detiene un oggetto femminile, e nulla altrimenti:

Person *pp; 
Female *fp; 
// ... 
fp = dynamic_cast<Female *> (pp); 
if (fp) 
    fp->DoFemaleThing(); 
else 
    cout << "Cast from Person to Female pointer failed"; 
Problemi correlati