Una volta mi è stata posta una domanda a sorpresa in un colloquio di lavoro: una classe basata su modelli richiede più memoria di un'altra classe che è identica ma non basata su modelli? La mia risposta era no, ma il fatto che abbia posto la domanda significa che probabilmente c'è un caso in cui c'è. O voleva davvero scopare con me. Quale sarebbe il caso in cui una classe basata su modelli richiederebbe più memoria?Una classe basata su modello è più grande della classe non modello utilizzando lo stesso tipo?
risposta
La prima cosa è chiarire qual è il significato della domanda. Se la domanda è se gli oggetti del tipo saranno più grandi (ad esempio sizeof(T<int>) > sizeof(T_int)
), la risposta è no. Se la domanda riguarda l'impronta binaria dell'applicazione stessa, incluso il codice per le funzioni, la risposta è che la dimensione complessiva del programma potrebbe effettivamente essere inferiore nel caso di un modello, poiché solo le funzioni membro utilizzate verranno assegnate a compilato (se non esplicitamente istanziato). Sebbene alla fine della giornata, il linker potrebbe potenzialmente scartare anche i membri non utilizzati dalla versione non-template.
Esiste un termine comune: codice bloat utilizzato per fare riferimento all'esplosione del codice generato dai modelli. Il termine si riferisce al fatto che ogni diversa istanziazione di un modello genererà le proprie funzioni e che può far sì che più funzioni siano presenti nell'eseguibile rispetto a un insieme più piccolo di funzioni non modello per le quali sono consentite le conversioni degli argomenti.
consideri una possibile interfaccia per un modello di vettore:
template <typename T>
class Vector {
template <typename U> void push_back(U u);
//....
Per ogni chiamata a push_back
con un diverso tipo di argomento, una nuova funzione verrà generato, quindi ci sarà una funzione per Vector<int>::push_back('a')
e un altro per Vector<int>::push_back(1)
. Confrontalo con l'interfaccia di std::vector
in cui la funzione membro non è un modello e il chiamante esegue la conversione del tipo.
Sebbene questa possa essere una fonte di file eseguibili di maggiori dimensioni, non ritengo che ciò sia ciò che è stato chiesto. In particolare, per un tipo di modello e il tipo equivalente non di modello per il tipo particolare istanziato, il codice generato dovrebbe essere equivalente (ignorando il fatto che i nomi storti tendono ad essere più grandi per i modelli :))
+1 Bella risposta. Spiegato quasi tutti i punti. – Nawaz
@Nawaz: Ho appena scaricato ciò che mi è venuto in mente considerando l'eseguibile finale (nel livello intermedio, per un modello il codice prima del collegamento potrebbe avere più definizioni di esattamente le stesse funzioni membro in ogni unità di traduzione, ma queste vengono scartate al momento del collegamento). Se hai in mente qualcos'altro per completare * quasi tutti *, sono interessato a sentirli :) –
No. Non ho nient'altro nella mia mente. Hai detto praticamente tutto quello che potevo pensare (al momento). Ho detto "quasi tutti" esattamente per la stessa ragione per cui non ho detto "tutti". Penso che sia saggio essere aperti alle possibilità. :-) – Nawaz
La risposta è NO, per quanto riguarda la memoria. Voglio dire, non deve necessariamente prendere più memoria, anche se qualche malvagio potrebbe scrivere un modello di classe solo per provare il suo punto che la versione del modello di classe richieda più memoria.
Tuttavia, il codice sorgente del modello di classe potrebbe essere maggiore (o minore per quella materia) rispetto a versioni non classificate di un clas per un valore particolare del/i parametro/i di tipo.
template<typename T>
struct point_t
{
T x, y, z;
};
struct point_int
{
int x, y, z;
};
std::cout << (sizeof(point_int) == sizeof(point_t<int>)) << std::end;
Stamperà true
(o 1
).
Nota solo che il layout di memoria di point_int
e point_t<int>
sarà lo stesso. Così si può anche lanciare in questo modo:
point_t<int> pt {10, 20, 30};
point_int pi = *reinterpret_cast<point_int*>(&pt);
std::cout << "{" << pi.x <<"," << pi.y <<"," << pi.z << "}" << std::endl;
Si stamperà {10, 20, 30}
.
Speranza che aiuta.
Il modello viene sostituito con i valori reali in ogni posizione in cui è stato rifrato in fase di compilazione. quindi se si dispone di una classe template dicono:
public List<T>
{
public T* MyT;
...
}
e il codice utilizza con un tipo specifico dicono: List, di quello che sta realmente accadendo che questo codice viene utilizzato:
public List<Point>
{
public Point *MyT;
....
}
Quindi è essenzialmente la stessa dimensione di qualsiasi altra classe non modello.
- 1. Classe non è un modello di classe
- 2. Sovraccarico della funzione modello nella classe template
- 3. Impossibile chiamare una funzione membro modello di una classe modello da un'altra classe modello
- 4. Costruttore di copia modello C++ su modello classe
- 5. Modello di funzione in classe non modello
- 6. Perché una classe modello derivata non ha accesso agli identificatori di una classe modello di base?
- 7. Rails non riesce a trovare il modello con lo stesso nome della classe Ruby
- 8. Modello di memoria della funzione modello all'interno della classe non modello?
- 9. Modello di classe nel modello di classe in C++
- 10. Registrare lo stesso tipo su più interfacce
- 11. C++: modello classe polimerica
- 12. Funzione statica non basata su modelli in classe di modelli
- 13. Corrispondenza del modello sul tipo Classe [_]?
- 14. AssociationTypeMismatch per lo stesso modello
- 15. Classe modello - Simboli non trovati
- 16. Downcasting della classe base non-template alla classe derivata basata su modelli: è possibile?
- 17. Specializzazione incompleta classe modello
- 18. istanza modello di classe
- 19. Modello di classe locale
- 20. Funzione friend modello di una classe template
- 21. all'interno della specializzazione del modello di classe
- 22. Un membro di una classe può avere lo stesso nome del suo tipo (un'altra classe)?
- 23. Django Admin: genera automaticamente più inline con lo stesso modello
- 24. Campo modello statico della classe template?
- 25. Classe del modello che si riferisce a se stesso come parametro del modello di modello?
- 26. Pacchetto parametri variabile multiplo per modello Classe
- 27. Diagramma classe StarUML: Come aggiungere manualmente Generics (Tipo di modello T) per una classe
- 28. C++ - Chiamare una funzione all'interno di una classe con lo stesso nome della classe
- 29. Qual è l'uso della classe derivata come parametro del modello?
- 30. Specializzazione std :: hash per classe nidificata in una classe modello
Ho il sospetto che Il fatto che abbia posto la domanda indica che ci sono persone che * pensano * che un modello di classe abbia più memoria di una classe non modello. –
no, non lo è. ci vuole esattamente lo stesso. –
Sì, 'modello di classe 'richiede più memoria di una classe normale, ma è nel file di origine perché è richiesto più testo. – iammilind