Mi proverò a indovinare:
Costruttore e distruttore C ++ non sono affatto funzioni: sono macro. Vengono inclusi nello scope in cui viene creato l'oggetto e l'ambito in cui l'oggetto viene distrutto. A sua volta, non c'è costruttore né distruttore, l'oggetto è solo IS.
In realtà, penso che le altre funzioni della classe non siano funzioni nè funzioni inline che DONT si inline perché prendi il loro indirizzo (il compilatore si rende conto che ci sei dentro e non inline o inline il codice in la funzione e ottimizza tale funzione) e a sua volta la funzione sembra "essere ancora lì", anche se non lo farebbe se non avessi preso l'indirizzo.
La tabella virtuale dell'oggetto "C ++" non è come un oggetto JavaScript, dove puoi ottenere il suo costruttore e creare oggetti da esso in fase di esecuzione tramite new XMLHttpRequest.constructor
, ma piuttosto una raccolta di puntatori a funzioni anonime che fungono da significa interfacciarsi con questo oggetto, escludendo la capacità di creare l'oggetto. E non ha nemmeno senso "cancellare" l'oggetto, perché è come cercare di eliminare una struttura, non è possibile: è solo un'etichetta dello stack, basta scriverla come preferisci sotto un'altra etichetta: sei libero di usa una classe come 4 numeri interi:
/* i imagine this string gets compiled into a struct, one of which's members happens to be a const char * which is initialized to exactly your string: no function calls are made during construction. */
std::string a = "hello, world";
int *myInt = (int *)(*((void **)&a));
myInt[0] = 3;
myInt[1] = 9;
myInt[2] = 20;
myInt[3] = 300;
Non c'è perdita di memoria, non ci sono problemi, tranne che hai sprecato in modo efficace un mucchio di spazio di stack che è riservato all'interfacciamento dell'oggetto e alla stringa, ma non distruggerà il tuo programma (finché non provi per usarlo come una stringa mai più).
In realtà, se le mie supposizioni precedenti sono corrette: il costo completo della stringa è solo il costo di memorizzare questi 32 byte e lo spazio costante della stringa: le funzioni vengono utilizzate solo in fase di compilazione e possono anche essere allineate e buttato via dopo che l'oggetto è stato creato e usato (come se si stesse lavorando con una struttura e ci si riferisse direttamente solo senza chiamate di funzione, ci sono sicuramente chiamate doppie anziché salti di funzione, ma di solito è più veloce e occupa meno spazio). In sostanza, ogni volta che chiami una funzione, il compilatore sostituisce semplicemente quella chiamata con le istruzioni per farlo letteralmente, con le eccezioni impostate dai progettisti di linguaggio.
Riepilogo: gli oggetti C ++ non hanno idea di cosa siano; tutti gli strumenti per l'interfacciamento con essi sono inline staticamente, e persi in fase di runtime. Ciò rende il lavoro con le classi efficiente come riempire le strutture con i dati e lavorare direttamente con quei dati senza chiamare alcuna funzione (queste funzioni sono in linea).
Questo è completamente diverso dagli approcci di COM / ObjectiveC e javascript, che mantengono le informazioni sul tipo in modo dinamico, a costo del sovraccarico di runtime, gestione della memoria, chiamate di costruzione, poiché il compilatore non può buttare via queste informazioni : è necessario per la spedizione dinamica. Questo a sua volta ci dà la possibilità di "Parlare" al nostro programma in fase di esecuzione, e di svilupparlo mentre è in esecuzione con componenti riflettenti.